[BAEL-3936] Initial commit

This commit is contained in:
kkaravitis 2020-04-05 00:45:15 +03:00
parent a1aa14b99a
commit 5a56276893
6 changed files with 437 additions and 3 deletions

View File

@ -48,6 +48,17 @@
<version>${postgres.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
@ -101,11 +112,28 @@
<configuration>
<sources>
<source>target/metamodel</source>
<source>${project.build.directory}/generated-sources/java/</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
@ -118,6 +146,7 @@
<maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
<maven-processor-plugin.version>3.3.3</maven-processor-plugin.version>
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
<querydsl.version>4.2.2</querydsl.version>
</properties>
</project>
</project>

View File

@ -0,0 +1,84 @@
package com.baeldung.jpa.unrelated.entities;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "cocktails")
public class Cocktail {
@Id
@Column(name="cocktail_name")
private String name;
@Column
private double price;
@Column(name="category")
private String category;
@OneToOne
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "cocktail_name",
referencedColumnName = "cocktail",
insertable = false,
updatable = false,
foreignKey = @javax.persistence.ForeignKey(value= ConstraintMode.NO_CONSTRAINT))
private Recipe recipe;
@OneToMany
@NotFound(action=NotFoundAction.IGNORE)
@JoinColumn(name = "cocktail",
referencedColumnName = "cocktail_name",
insertable = false,
updatable = false,
foreignKey = @javax.persistence.ForeignKey(value= ConstraintMode.NO_CONSTRAINT))
private List<MultipleRecipe> recipeList;
public Cocktail() {
}
public Cocktail(String name, double price, String baseIngredient) {
this.name = name;
this.price = price;
this.category = baseIngredient;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public String getCategory() {
return category;
}
public Recipe getRecipe() {
return recipe;
}
public List<MultipleRecipe> getRecipeList() {
return recipeList;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cocktail cocktail = (Cocktail) o;
return Double.compare(cocktail.price, price) == 0 &&
Objects.equals(name, cocktail.name) &&
Objects.equals(category, cocktail.category);
}
@Override
public int hashCode() {
return Objects.hash(name, price, category);
}
}

View File

@ -0,0 +1,65 @@
package com.baeldung.jpa.unrelated.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Objects;
@Entity
@Table(name="multiple_recipes")
public class MultipleRecipe {
@Id
@Column(name="id")
private Long id;
@Column(name="cocktail")
private String cocktail;
@Column(name="instructions")
private String instructions;
@Column(name="base_ingredient")
private String baseIngredient;
public MultipleRecipe() {}
public MultipleRecipe(Long id, String cocktail, String instructions, String baseIngredient) {
this.baseIngredient = baseIngredient;
this.cocktail = cocktail;
this.id = id;
this.instructions = instructions;
}
public Long getId() {
return id;
}
public String getCocktail() {
return cocktail;
}
public String getInstructions() {
return instructions;
}
public String getBaseIngredient() {
return baseIngredient;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MultipleRecipe that = (MultipleRecipe) o;
return Objects.equals(id, that.id) &&
Objects.equals(cocktail, that.cocktail) &&
Objects.equals(instructions, that.instructions) &&
Objects.equals(baseIngredient, that.baseIngredient);
}
@Override
public int hashCode() {
return Objects.hash(id, cocktail, instructions, baseIngredient);
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.jpa.unrelated.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Objects;
@Entity
@Table(name="recipes")
public class Recipe {
@Id
@Column(name = "cocktail")
private String cocktail;
@Column
private String instructions;
public Recipe() {
}
public Recipe(String cocktail, String instructions) {
this.cocktail = cocktail;
this.instructions = instructions;
}
public String getCocktail() {
return cocktail;
}
public String getInstructions() {
return instructions;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Recipe recipe = (Recipe) o;
return Objects.equals(cocktail, recipe.cocktail) &&
Objects.equals(instructions, recipe.instructions);
}
@Override
public int hashCode() {
return Objects.hash(cocktail, instructions);
}
}

View File

@ -162,5 +162,26 @@
value="false" />
</properties>
</persistence-unit>
</persistence>
<persistence-unit name="jpa-h2-unrelated-entities">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.unrelated.entities.Cocktail</class>
<class>com.baeldung.jpa.unrelated.entities.Recipe</class>
<class>com.baeldung.jpa.unrelated.entities.MultipleRecipe</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="show_sql" value="true" />
<property name="hibernate.temp.use_jdbc_metadata_defaults"
value="false" />
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,187 @@
package com.baeldung.jpa.unrelated.entities;
import javax.persistence.*;
import com.querydsl.jpa.impl.JPAQuery;
import org.junit.jupiter.api.*;
import java.util.List;
import java.util.function.Consumer;
import static org.junit.jupiter.api.Assertions.*;
public class UnrelatedEntitiesUnitTest {
private static EntityManagerFactory entityManagerFactory;
private static EntityManager entityManager;
private static Cocktail mojito;
private static Cocktail ginTonic;
@BeforeAll
public static void setup() {
entityManagerFactory = Persistence.createEntityManagerFactory("jpa-h2-unrelated-entities");
entityManager = entityManagerFactory.createEntityManager();
mojito = new Cocktail("Mojito", 11, "Rum");
ginTonic = new Cocktail("Gin tonic", 8.50, "Gin");
entityManager.getTransaction().begin();
entityManager.persist(mojito);
entityManager.persist(ginTonic);
entityManager.persist(new Recipe(mojito.getName(), "Some instructions"));
entityManager.persist(new MultipleRecipe(1L, mojito.getName(), "some instructions", mojito.getCategory()));
entityManager.persist(new MultipleRecipe(2L, mojito.getName(), "some other instructions", mojito.getCategory()));
entityManager.getTransaction().commit();
}
@AfterAll
public static void closeSession() {
entityManager.close();
}
@Test
public void whenQueryingForCocktailThatHasRecipe_thenTheExpectedCocktailReturned() {
// JPA
Cocktail cocktail = entityManager.createQuery(
"select c from Cocktail c join c.recipe", Cocktail.class)
.getSingleResult();
verifyResult(mojito, cocktail);
cocktail = entityManager.createQuery(
"select c from Cocktail c join Recipe r on c.name = r.cocktail", Cocktail.class)
.getSingleResult();
verifyResult(mojito, cocktail);
// QueryDSL
cocktail = new JPAQuery<Cocktail>(entityManager)
.from(QCocktail.cocktail)
.join(QCocktail.cocktail.recipe)
.fetchOne();
verifyResult(mojito, cocktail);
cocktail = new JPAQuery<Cocktail>(entityManager)
.from(QCocktail.cocktail)
.join(QRecipe.recipe)
.on(QCocktail.cocktail.name.eq(QRecipe.recipe.cocktail))
.fetchOne();
verifyResult(mojito, cocktail);
}
@Test
public void whenQueryingForCocktailThatHasNotARecipe_thenTheExpectedCocktailReturned() {
Cocktail cocktail = entityManager
.createQuery("select c from Cocktail c left join c.recipe r " +
"where r is null",
Cocktail.class)
.getSingleResult();
verifyResult(ginTonic, cocktail);
cocktail = entityManager
.createQuery("select c from Cocktail c left join Recipe r " +
"on c.name = r.cocktail " +
"where r is null",
Cocktail.class)
.getSingleResult();
verifyResult(ginTonic, cocktail);
QRecipe recipe = new QRecipe("alias");
cocktail = new JPAQuery<Cocktail>(entityManager)
.from(QCocktail.cocktail)
.leftJoin(QCocktail.cocktail.recipe, recipe)
.where(recipe.isNull()).fetchOne();
verifyResult(ginTonic, cocktail);
cocktail = new JPAQuery<Cocktail>(entityManager)
.from(QCocktail.cocktail)
.leftJoin(QRecipe.recipe)
.on(QCocktail.cocktail.name.eq(QRecipe.recipe.cocktail))
.where(QRecipe.recipe.isNull()).fetchOne();
verifyResult(ginTonic, cocktail);
}
@Test
public void whenQueringForCocktailThatHasRecipes_thenTheExpectedCocktailReturned() {
// JPQL
Cocktail cocktail = entityManager
.createQuery("select c from Cocktail c join c.recipeList", Cocktail.class)
.getSingleResult();
verifyResult(mojito, cocktail);
cocktail = entityManager
.createQuery("select c from Cocktail c join MultipleRecipe mr on mr.cocktail = c.name", Cocktail.class)
.getSingleResult();
verifyResult(mojito, cocktail);
// QueryDSL
cocktail = new JPAQuery<Cocktail>(entityManager)
.from(QCocktail.cocktail).join(QCocktail.cocktail.recipeList).fetchOne();
verifyResult(mojito, cocktail);
cocktail = new JPAQuery<Cocktail>(entityManager).from(QCocktail.cocktail)
.join(QMultipleRecipe.multipleRecipe)
.on(QCocktail.cocktail.name.eq(QMultipleRecipe.multipleRecipe.cocktail))
.fetchOne();
verifyResult(mojito, cocktail);
}
@Test
public void whenQueryingForCocktailThatHasNotRecipes_thenTheExpectedCocktailReturned() {
// JPQL
Cocktail cocktail = entityManager
.createQuery("select c from Cocktail c left join c.recipeList r where r is null", Cocktail.class)
.getSingleResult();
verifyResult(ginTonic, cocktail);
cocktail = entityManager.createQuery("select c from Cocktail c left join MultipleRecipe r " +
"on c.name = r.cocktail where r is null", Cocktail.class)
.getSingleResult();
verifyResult(ginTonic, cocktail);
// QueryDSL
QMultipleRecipe multipleRecipe = new QMultipleRecipe("alias");
cocktail = new JPAQuery<Cocktail>(entityManager)
.from(QCocktail.cocktail)
.leftJoin(QCocktail.cocktail.recipeList, multipleRecipe)
.where(multipleRecipe.isNull())
.fetchOne();
verifyResult(ginTonic, cocktail);
cocktail = new JPAQuery<Cocktail>(entityManager)
.from(QCocktail.cocktail).leftJoin(QMultipleRecipe.multipleRecipe)
.on(QCocktail.cocktail.name.eq(QMultipleRecipe.multipleRecipe.cocktail))
.where(QMultipleRecipe.multipleRecipe.isNull()).fetchOne();
verifyResult(ginTonic, cocktail);
}
@Test
public void whenQueryingForRumCocktailsInMenuRecipes_thenTheExpectedRecipesReturned() {
Consumer<List<MultipleRecipe>> verifyResult = recipes -> {
assertEquals(2, recipes.size());
recipes.forEach(r -> assertEquals(mojito.getName(), r.getCocktail()));
};
// JPQL
List<MultipleRecipe> recipes = entityManager
.createQuery("select distinct r from MultipleRecipe r join Cocktail c " +
"on r.cocktail = c.name " +
"and " +
"r.baseIngredient = :category",
MultipleRecipe.class)
.setParameter("category", mojito.getCategory())
.getResultList();
verifyResult.accept(recipes);
// QueryDSL
QCocktail cocktail = QCocktail.cocktail;
QMultipleRecipe multipleRecipe = QMultipleRecipe.multipleRecipe;
recipes = new JPAQuery<MultipleRecipe>(entityManager)
.from(multipleRecipe)
.join(cocktail)
.on(multipleRecipe.cocktail.eq(cocktail.name)
.and(multipleRecipe.baseIngredient.eq(mojito.getCategory())))
.fetch();
verifyResult.accept(recipes);
}
private void verifyResult(Cocktail expectedCocktail, Cocktail queryResult) {
assertNotNull(queryResult);
assertEquals(expectedCocktail, queryResult);
}
}