BAEL-5986 - Getting Started with Blaze Persistence (#13107)

* BAEL-5986 - Getting Started with Blaze Persistence

* Optimize imports

* Fix test class name

* Switch to JUnit5

* Removed dependencies and Controller classes

* Update pom.xml

* Update Configuration class
This commit is contained in:
apeterlic 2022-12-09 18:40:18 +01:00 committed by GitHub
parent 0264bb82c8
commit 10d561451a
18 changed files with 643 additions and 0 deletions

View File

@ -0,0 +1 @@
### Relevant Articles:

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>blaze-persistence</artifactId>
<version>1.0-SNAPSHOT</version>
<name>blaze-persistence</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<blaze-persistence.version>1.6.8</blaze-persistence.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-bom</artifactId>
<version>${blaze-persistence.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Core dependencies -->
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-core-api</artifactId>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-core-impl</artifactId>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-hibernate-5.4</artifactId>
</dependency>
<!-- Entity View dependencies -->
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-entity-view-api</artifactId>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-entity-view-impl</artifactId>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-entity-view-processor</artifactId>
</dependency>
<!-- Spring integration dependencies -->
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-entity-view-spring</artifactId>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-spring-data-2.4</artifactId>
</dependency>
<!-- Spring dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,57 @@
package com.baeldung;
import com.baeldung.model.Person;
import com.baeldung.model.Post;
import com.baeldung.repository.PersonRepository;
import com.baeldung.repository.PostRepository;
import com.baeldung.repository.PostViewRepository;
import com.baeldung.view.PostWithAuthorView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BlazePersistenceApplication implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(BlazePersistenceApplication.class);
@Autowired
private PersonRepository personRepository;
@Autowired
private PostRepository postRepository;
@Autowired
private PostViewRepository postViewRepository;
public static void main(String[] args) {
SpringApplication.run(BlazePersistenceApplication.class, args);
}
@Override
public void run(String... args) {
logger.info("All Posts:");
Iterable<Post> posts = postRepository.findAll();
posts.forEach(p -> logger.info(String.valueOf(p)));
logger.info("Posts with title 'Spring' or author 'Peter':");
Iterable<PostWithAuthorView> postsFiltered = postRepository.findBy("Spring", "Peter");
postsFiltered.forEach(p -> logger.info(String.valueOf(p)));
logger.info("Find all post with author view:");
Iterable<PostWithAuthorView> postsView = postViewRepository.findAll();
postsView.forEach(p -> logger.info(String.valueOf(p)));
logger.info("Person with at least two posts:");
Iterable<Person> personIterable = personRepository.find();
personIterable.forEach(p -> logger.info(String.valueOf(p)));
logger.info("All Persons:");
Iterable<Person> personIterableAll = personRepository.findAll();
personIterableAll.forEach(p -> logger.info(String.valueOf(p)));
}
}

View File

@ -0,0 +1,35 @@
package com.baeldung.config;
import com.blazebit.persistence.Criteria;
import com.blazebit.persistence.CriteriaBuilderFactory;
import com.blazebit.persistence.integration.view.spring.EnableEntityViews;
import com.blazebit.persistence.spi.CriteriaBuilderConfiguration;
import com.blazebit.persistence.spring.data.repository.config.EnableBlazeRepositories;
import com.blazebit.persistence.view.EntityViewManager;
import com.blazebit.persistence.view.spi.EntityViewConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManagerFactory;
@Configuration
@EnableEntityViews(basePackages = {"com.baeldung.view"})
@EnableBlazeRepositories(basePackages = "com.baeldung.repository")
public class BlazePersistenceConfiguration {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Bean
public CriteriaBuilderFactory createCriteriaBuilderFactory() {
CriteriaBuilderConfiguration config = Criteria.getDefault();
return config.createCriteriaBuilderFactory(entityManagerFactory);
}
@Bean
public EntityViewManager createEntityViewManager(CriteriaBuilderFactory criteriaBuilderFactory,
EntityViewConfiguration entityViewConfiguration) {
return entityViewConfiguration.createEntityViewManager(criteriaBuilderFactory);
}
}

View File

@ -0,0 +1,72 @@
package com.baeldung.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import java.util.HashSet;
import java.util.Set;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
private int age;
@OneToMany(mappedBy = "author")
private Set<Post> posts = new HashSet<>();
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Post> getPosts() {
return posts;
}
public void setPosts(Set<Post> posts) {
this.posts = posts;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}

View File

@ -0,0 +1,68 @@
package com.baeldung.model;
import javax.persistence.*;
@Entity
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
private String content;
@ManyToOne(fetch = FetchType.LAZY)
private Person author;
public Post() {
}
public Post(String title, String content, Person author) {
this.title = title;
this.content = content;
this.author = author;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Person getAuthor() {
return author;
}
public void setAuthor(Person author) {
this.author = author;
}
@Override
public String toString() {
return "Post{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.repository;
import com.baeldung.model.Person;
import com.baeldung.model.Post;
import com.blazebit.persistence.CriteriaBuilder;
import com.blazebit.persistence.CriteriaBuilderFactory;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
@Repository
@Transactional
public class PersonRepository {
private final EntityManager entityManager;
private final CriteriaBuilderFactory builderFactory;
public PersonRepository(EntityManager entityManager, CriteriaBuilderFactory builderFactory) {
this.entityManager = entityManager;
this.builderFactory = builderFactory;
}
public Iterable<Post> findPostsByPerson() {
CriteriaBuilder<Post> postCriteriaBuilder = builderFactory.create(entityManager, Post.class)
.from(Person.class, "person")
.select("person.posts");
return postCriteriaBuilder.getResultList();
}
public Iterable<Person> findAll() {
return builderFactory.create(entityManager, Person.class).getResultList();
}
public Iterable<Person> find() {
CriteriaBuilder<Person> personCriteriaBuilder = builderFactory.create(entityManager, Person.class, "p")
.where("p.age")
.betweenExpression("18")
.andExpression("40")
.where("SIZE(p.posts)").geExpression("2")
.orderByAsc("p.name")
.orderByAsc("p.id");
return personCriteriaBuilder.getResultList();
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.repository;
import com.baeldung.model.Post;
import com.baeldung.view.PostWithAuthorView;
import com.blazebit.persistence.CriteriaBuilder;
import com.blazebit.persistence.CriteriaBuilderFactory;
import com.blazebit.persistence.view.EntityViewManager;
import com.blazebit.persistence.view.EntityViewSetting;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
@Repository
@Transactional
public class PostRepository {
private final EntityManager entityManager;
private final CriteriaBuilderFactory builderFactory;
private final EntityViewManager viewManager;
public PostRepository(EntityManager entityManager, CriteriaBuilderFactory builderFactory,
EntityViewManager viewManager) {
this.entityManager = entityManager;
this.builderFactory = builderFactory;
this.viewManager = viewManager;
}
public Iterable<Post> findAll() {
return builderFactory.create(entityManager, Post.class).getResultList();
}
public Iterable<PostWithAuthorView> findBy(final String title, final String authorName) {
CriteriaBuilder<Post> postCriteriaBuilder = builderFactory.create(entityManager, Post.class, "p")
.whereOr()
.where("p.title").like().value(title + "%").noEscape()
.where("p.author.name").eq(authorName)
.endOr();
CriteriaBuilder<PostWithAuthorView> postWithAuthorViewCriteriaBuilder =
viewManager.applySetting(EntityViewSetting
.create(PostWithAuthorView.class), postCriteriaBuilder);
return postWithAuthorViewCriteriaBuilder.getResultList();
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.repository;
import com.baeldung.view.PostWithAuthorView;
import com.blazebit.persistence.spring.data.repository.EntityViewRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional(readOnly = true)
public interface PostViewRepository extends EntityViewRepository<PostWithAuthorView, Long> {
}

View File

@ -0,0 +1,16 @@
package com.baeldung.view;
import com.baeldung.model.Person;
import com.blazebit.persistence.view.EntityView;
import com.blazebit.persistence.view.IdMapping;
@EntityView(Person.class)
public interface PersonView {
@IdMapping
Long getId();
int getAge();
String getName();
}

View File

@ -0,0 +1,18 @@
package com.baeldung.view;
import com.baeldung.model.Post;
import com.blazebit.persistence.view.EntityView;
import com.blazebit.persistence.view.IdMapping;
import com.blazebit.persistence.view.Mapping;
@EntityView(Post.class)
public interface PostView {
@IdMapping
Long getId();
@Mapping("UPPER(title)")
String getTitle();
String getContent();
}

View File

@ -0,0 +1,10 @@
package com.baeldung.view;
import com.baeldung.model.Post;
import com.blazebit.persistence.view.EntityView;
@EntityView(Post.class)
public interface PostWithAuthorView extends PostView {
PersonView getAuthor();
}

View File

@ -0,0 +1,9 @@
spring.h2.console.enabled=true
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

View File

@ -0,0 +1,11 @@
INSERT INTO Person(id, name, age) VALUES(1, 'Peter', 18);
INSERT INTO Person(id, name, age) VALUES(2, 'Emily', 36);
INSERT INTO Person(id, name, age) VALUES(3, 'John', 27);
INSERT INTO Post(id, title, content, author_id) VALUES(1, 'Blaze Persistence', 'Blaze Content', 1);
INSERT INTO Post(id, title, content, author_id) VALUES(2, 'Jacoco', 'Jacoco Content', 1);
INSERT INTO Post(id, title, content, author_id) VALUES(3, 'Spring', 'Spring Content', 2);
INSERT INTO Post(id, title, content, author_id) VALUES(4, 'Spring Boot', 'Spring Boot Content', 3);
INSERT INTO Post(id, title, content, author_id) VALUES(5, 'Java 17', 'Java Content', 3);
INSERT INTO Post(id, title, content, author_id) VALUES(6, 'Functional Programming', 'Functional Programming Content', 3);
INSERT INTO Post(id, title, content, author_id) VALUES(7, 'Unit Testing', 'Unit Testing Content', 3);

View File

@ -0,0 +1,49 @@
package com.baeldung;
import com.baeldung.model.Person;
import com.baeldung.model.Post;
import com.baeldung.repository.PersonRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ContextConfiguration(classes = TestContextConfig.class)
@ExtendWith(SpringExtension.class)
public class PersonUnitTest {
@Autowired
private PersonRepository personRepository;
@Test
public void whenFind_thenReturnCorrectListSize() {
final Iterable<Person> listIterable = personRepository.find();
final List<Person> list = new ArrayList<>();
listIterable.forEach(list::add);
assertEquals(2, list.size());
assertEquals("John", list.get(0).getName());
}
@Test
public void whenFindAll_thenReturnCorrectListSize() {
final Iterable<Person> listIterable = personRepository.findAll();
final List<Person> list = new ArrayList<>();
listIterable.forEach(list::add);
assertEquals(3, list.size());
}
@Test
public void whenFindPostsByPerson_thenReturnCorrectListSize() {
final Iterable<Post> listIterable = personRepository.findPostsByPerson();
final List<Post> list = new ArrayList<>();
listIterable.forEach(list::add);
assertEquals(7, list.size());
}
}

View File

@ -0,0 +1,54 @@
package com.baeldung;
import com.baeldung.model.Post;
import com.baeldung.repository.PostRepository;
import com.baeldung.repository.PostViewRepository;
import com.baeldung.view.PostView;
import com.baeldung.view.PostWithAuthorView;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ContextConfiguration(classes = TestContextConfig.class)
@ExtendWith(SpringExtension.class)
public class PostUnitTest {
@Autowired
private PostViewRepository postViewRepository;
@Autowired
private PostRepository postRepository;
@Test
public void whenFindAll_thenReturnCorrectListViewSize() {
final Iterable<PostWithAuthorView> listIterable = postViewRepository.findAll();
final List<PostView> list = new ArrayList<>();
listIterable.forEach(list::add);
assertEquals(7, list.size());
}
@Test
public void givenPostIdAndAuthorName_whenFind_thenReturnCorrectResult() {
final Iterable<PostWithAuthorView> listIterable =
postRepository.findBy("Spring", "Peter");
final List<PostView> list = new ArrayList<>();
listIterable.forEach(list::add);
assertEquals(4, list.size());
}
@Test
public void whenFindAll_thenReturnCorrectListSize() {
final Iterable<Post> listIterable = postRepository.findAll();
final List<Post> list = new ArrayList<>();
listIterable.forEach(list::add);
assertEquals(7, list.size());
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung;
import com.blazebit.persistence.integration.view.spring.EnableEntityViews;
import com.blazebit.persistence.spring.data.repository.config.EnableBlazeRepositories;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.baeldung")
@EnableEntityViews(basePackages = {"com.baeldung.view"})
@EnableBlazeRepositories(basePackages = "com.baeldung.repository")
public class TestContextConfig {
}

View File

@ -18,6 +18,7 @@
<module>apache-bookkeeper</module>
<module>apache-cayenne</module>
<module>apache-derby</module>
<module>blaze-persistence</module>
<module>core-java-persistence</module>
<module>core-java-persistence-2</module>
<module>deltaspike</module>