From ff76cbc1fe12379b6e28ff63fb4ae80daa8a678e Mon Sep 17 00:00:00 2001 From: Jose Carvajal Date: Sat, 3 Feb 2018 05:00:27 +0100 Subject: [PATCH] Bael 113 (#3484) * BAEL-399: A Guide to Multitenancy in Hibernate 5 * Removed unused properties in profile 2 * Changes after code review * BAEL-113 * Changes after code review * Added main method in spring boot application * Removed extra files --- pom.xml | 1 + spring-jinq/pom.xml | 83 +++++++++++++++++++ .../baeldung/spring/jinq/JinqApplication.java | 12 +++ .../config/JinqProviderConfiguration.java | 18 ++++ .../baeldung/spring/jinq/entities/Car.java | 58 +++++++++++++ .../spring/jinq/entities/Manufacturer.java | 42 ++++++++++ .../repositories/BaseJinqRepositoryImpl.java | 26 ++++++ .../jinq/repositories/CarRepository.java | 27 ++++++ .../jinq/repositories/CarRepositoryImpl.java | 72 ++++++++++++++++ .../src/main/resources/application.properties | 7 ++ .../CarRepositoryIntegrationTest.java | 42 ++++++++++ 11 files changed, 388 insertions(+) create mode 100644 spring-jinq/pom.xml create mode 100644 spring-jinq/src/main/java/com/baeldung/spring/jinq/JinqApplication.java create mode 100644 spring-jinq/src/main/java/com/baeldung/spring/jinq/config/JinqProviderConfiguration.java create mode 100644 spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Car.java create mode 100644 spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Manufacturer.java create mode 100644 spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/BaseJinqRepositoryImpl.java create mode 100644 spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/CarRepository.java create mode 100644 spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/CarRepositoryImpl.java create mode 100644 spring-jinq/src/main/resources/application.properties create mode 100644 spring-jinq/src/test/java/com/baeldung/spring/jinq/repositories/CarRepositoryIntegrationTest.java diff --git a/pom.xml b/pom.xml index 4a25459fcb..582ee6696e 100644 --- a/pom.xml +++ b/pom.xml @@ -246,6 +246,7 @@ spring-zuul spring-reactor spring-vertx + spring-jinq spring-rest-embedded-tomcat diff --git a/spring-jinq/pom.xml b/spring-jinq/pom.xml new file mode 100644 index 0000000000..a895ae8dd4 --- /dev/null +++ b/spring-jinq/pom.xml @@ -0,0 +1,83 @@ + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + 4.0.0 + spring-jinq + 0.1-SNAPSHOT + + spring-jinq + + jar + + + UTF-8 + 1.8 + + 1.8.22 + + + + + + org.springframework.boot + spring-boot-dependencies + 1.5.9.RELEASE + pom + import + + + + + + + org.jinq + jinq-jpa + ${jinq.version} + + + + + com.h2database + h2 + + + + org.hibernate + hibernate-entitymanager + + + + + org.springframework + spring-orm + + + + + org.springframework.boot + spring-boot-starter-test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + false + + + + + + diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/JinqApplication.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/JinqApplication.java new file mode 100644 index 0000000000..d53b585d36 --- /dev/null +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/JinqApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.jinq; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JinqApplication { + + public static void main(String[] args) { + SpringApplication.run(JinqApplication.class, args); + } +} diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/config/JinqProviderConfiguration.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/config/JinqProviderConfiguration.java new file mode 100644 index 0000000000..6d921045b7 --- /dev/null +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/config/JinqProviderConfiguration.java @@ -0,0 +1,18 @@ +package com.baeldung.spring.jinq.config; + +import javax.persistence.EntityManagerFactory; + +import org.jinq.jpa.JinqJPAStreamProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JinqProviderConfiguration { + + @Bean + @Autowired + JinqJPAStreamProvider jinqProvider(EntityManagerFactory emf) { + return new JinqJPAStreamProvider(emf); + } +} diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Car.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Car.java new file mode 100644 index 0000000000..263e6c7622 --- /dev/null +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Car.java @@ -0,0 +1,58 @@ +package com.baeldung.spring.jinq.entities; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; + +@Entity(name = "CAR") +public class Car { + private String model; + private String description; + private int year; + private String engine; + private Manufacturer manufacturer; + + @Id + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public String getEngine() { + return engine; + } + + public void setEngine(String engine) { + this.engine = engine; + } + + @OneToOne + @JoinColumn(name = "name") + public Manufacturer getManufacturer() { + return manufacturer; + } + + public void setManufacturer(Manufacturer manufacturer) { + this.manufacturer = manufacturer; + } +} diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Manufacturer.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Manufacturer.java new file mode 100644 index 0000000000..f6e5fd23de --- /dev/null +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Manufacturer.java @@ -0,0 +1,42 @@ +package com.baeldung.spring.jinq.entities; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity(name = "MANUFACTURER") +public class Manufacturer { + + private String name; + private String city; + private List cars; + + @Id + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + @OneToMany(mappedBy = "model") + public List getCars() { + return cars; + } + + public void setCars(List cars) { + this.cars = cars; + } + +} diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/BaseJinqRepositoryImpl.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/BaseJinqRepositoryImpl.java new file mode 100644 index 0000000000..42b81ecc59 --- /dev/null +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/BaseJinqRepositoryImpl.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.jinq.repositories; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.jinq.jpa.JPAJinqStream; +import org.jinq.jpa.JinqJPAStreamProvider; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class BaseJinqRepositoryImpl { + @Autowired + private JinqJPAStreamProvider jinqDataProvider; + + @PersistenceContext + private EntityManager entityManager; + + protected abstract Class entityType(); + + public JPAJinqStream stream() { + return streamOf(entityType()); + } + + protected JPAJinqStream streamOf(Class clazz) { + return jinqDataProvider.streamAll(entityManager, clazz); + } +} diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/CarRepository.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/CarRepository.java new file mode 100644 index 0000000000..56f6106e08 --- /dev/null +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/CarRepository.java @@ -0,0 +1,27 @@ +package com.baeldung.spring.jinq.repositories; + +import java.util.List; +import java.util.Optional; + +import org.jinq.tuples.Pair; +import org.jinq.tuples.Tuple3; + +import com.baeldung.spring.jinq.entities.Car; +import com.baeldung.spring.jinq.entities.Manufacturer; + +public interface CarRepository { + + Optional findByModel(String model); + + List findByModelAndDescription(String model, String desc); + + List> findWithModelYearAndEngine(); + + Optional findManufacturerByModel(String model); + + List> findCarsPerManufacturer(); + + long countCarsByModel(String model); + + List findAll(int skip, int limit); +} diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/CarRepositoryImpl.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/CarRepositoryImpl.java new file mode 100644 index 0000000000..bf16c87461 --- /dev/null +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/CarRepositoryImpl.java @@ -0,0 +1,72 @@ +package com.baeldung.spring.jinq.repositories; + +import java.util.List; +import java.util.Optional; + +import org.jinq.orm.stream.JinqStream; +import org.jinq.tuples.Pair; +import org.jinq.tuples.Tuple3; +import org.springframework.stereotype.Repository; + +import com.baeldung.spring.jinq.entities.Car; +import com.baeldung.spring.jinq.entities.Manufacturer; + +@Repository +public class CarRepositoryImpl extends BaseJinqRepositoryImpl implements CarRepository { + + @Override + public Optional findByModel(String model) { + return stream().where(c -> c.getModel() + .equals(model)) + .findFirst(); + } + + @Override + public List findByModelAndDescription(String model, String desc) { + return stream().where(c -> c.getModel() + .equals(model) + && c.getDescription() + .contains(desc)) + .toList(); + } + + @Override + public List> findWithModelYearAndEngine() { + return stream().select(c -> new Tuple3<>(c.getModel(), c.getYear(), c.getEngine())) + .toList(); + } + + @Override + public Optional findManufacturerByModel(String model) { + return stream().where(c -> c.getModel() + .equals(model)) + .select(c -> c.getManufacturer()) + .findFirst(); + } + + @Override + public List> findCarsPerManufacturer() { + return streamOf(Manufacturer.class).join(m -> JinqStream.from(m.getCars())) + .toList(); + } + + @Override + public long countCarsByModel(String model) { + return stream().where(c -> c.getModel() + .equals(model)) + .count(); + } + + @Override + public List findAll(int skip, int limit) { + return stream().skip(skip) + .limit(limit) + .toList(); + } + + @Override + protected Class entityType() { + return Car.class; + } + +} diff --git a/spring-jinq/src/main/resources/application.properties b/spring-jinq/src/main/resources/application.properties new file mode 100644 index 0000000000..dc73bed0c5 --- /dev/null +++ b/spring-jinq/src/main/resources/application.properties @@ -0,0 +1,7 @@ +spring.datasource.url=jdbc:h2:~/jinq +spring.datasource.username=sa +spring.datasource.password= + +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true \ No newline at end of file diff --git a/spring-jinq/src/test/java/com/baeldung/spring/jinq/repositories/CarRepositoryIntegrationTest.java b/spring-jinq/src/test/java/com/baeldung/spring/jinq/repositories/CarRepositoryIntegrationTest.java new file mode 100644 index 0000000000..9cb126cbaa --- /dev/null +++ b/spring-jinq/src/test/java/com/baeldung/spring/jinq/repositories/CarRepositoryIntegrationTest.java @@ -0,0 +1,42 @@ +package com.baeldung.spring.jinq.repositories; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.jinq.JinqApplication; + +@ContextConfiguration(classes = JinqApplication.class) +@RunWith(SpringJUnit4ClassRunner.class) +public class CarRepositoryIntegrationTest { + + @Autowired + private CarRepository repository; + + @Test + public void givenACar_whenFilter_thenShouldBeFound() { + assertThat(repository.findByModel("model1") + .isPresent()).isFalse(); + } + + @Test + public void givenACar_whenMultipleFilters_thenShouldBeFound() { + assertThat(repository.findByModelAndDescription("model1", "desc") + .isEmpty()).isTrue(); + } + + @Test + public void whenUseASelectClause() { + assertThat(repository.findWithModelYearAndEngine() + .isEmpty()).isTrue(); + } + + @Test + public void whenUsingOneToOneRelationship() { + assertThat(repository.findManufacturerByModel("model1")).isNotNull(); + } +}