From 87fc258109265f80e3d9ec4126395555dc7422a4 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Wed, 17 May 2023 14:26:48 +0200 Subject: [PATCH] HHH-16570 Add test for issue --- .../test/batch/BatchAndBagCollectionTest.java | 161 ++++++++++++++ .../test/batch/SetAndBagCollectionTest.java | 206 ++++++++++++++++++ .../collection/SetAndBagCollectionTest.java | 197 +++++++++++++++++ 3 files changed, 564 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/batch/BatchAndBagCollectionTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/batch/SetAndBagCollectionTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/collection/SetAndBagCollectionTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/batch/BatchAndBagCollectionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/batch/BatchAndBagCollectionTest.java new file mode 100644 index 0000000000..f56b0537ba --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/batch/BatchAndBagCollectionTest.java @@ -0,0 +1,161 @@ +/* + * Copyright 2014 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hibernate.orm.test.batch; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.cfg.AvailableSettings; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +import static org.assertj.core.api.Assertions.assertThat; + +@DomainModel( + annotatedClasses = { + BatchAndBagCollectionTest.EntityA.class, + BatchAndBagCollectionTest.EntityB.class + } +) +@ServiceRegistry( + settings = { + @Setting(name = AvailableSettings.DEFAULT_BATCH_FETCH_SIZE, value = "10") + } +) +@SessionFactory +@JiraKey("HHH-16570") +public class BatchAndBagCollectionTest { + + @BeforeAll + public void setUp(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + EntityA entityA = new EntityA( 1 ); + EntityA childA1 = new EntityA( 2 ); + EntityA childA2 = new EntityA( 3 ); + + EntityB entityB1 = new EntityB(); + EntityB entityB2 = new EntityB(); + EntityB entityB3 = new EntityB(); + + entityA.addChild( childA1 ); + entityA.addChild( childA2 ); + + childA1.setListOfEntitiesB( List.of( entityB1, entityB2, entityB3 ) ); + + session.persist( entityA ); + session.persist( childA1 ); + session.persist( childA2 ); + session.persist( entityB1 ); + session.persist( entityB2 ); + session.persist( entityB3 ); + } + ); + + } + + @Test + public void testOneToManyHasCorrectSize(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + List entitiesA = session.createQuery( + "select a from EntityA a where a.parent is null", + EntityA.class + ) + .getResultList(); + assertThat( entitiesA ).hasSize( 1 ); + EntityA entityA = entitiesA.get( 0 ); + assertThat( entityA.getId() ).isEqualTo( 1 ); + assertThat( entityA.getChildren() ).hasSize( 2 ); + } + ); + } + + @Entity(name = "EntityA") + @Table(name = "ENTITY_A") + public static class EntityA { + @Id + Integer id; + + String name; + + @ManyToOne + EntityA parent; + + @OneToMany(mappedBy = "parent") + List children = new ArrayList<>(); + + @OneToMany + @Fetch(FetchMode.JOIN) + List listOfEntitiesB = new ArrayList<>(); + + public EntityA() { + } + + public EntityA(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public void setListOfEntitiesB(List listOfEntitiesB) { + this.listOfEntitiesB = listOfEntitiesB; + } + + public void addChild(EntityA childA) { + children.add( childA ); + childA.parent = this; + } + } + + @Entity(name = "EntityB") + @Table(name = "ENTITY_B") + public static class EntityB { + @Id + @GeneratedValue + @Column(name = "ID") + Integer id; + + String name; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/batch/SetAndBagCollectionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/batch/SetAndBagCollectionTest.java new file mode 100644 index 0000000000..adb41137bc --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/batch/SetAndBagCollectionTest.java @@ -0,0 +1,206 @@ +package org.hibernate.orm.test.batch; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.hibernate.cfg.AvailableSettings; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +import static org.assertj.core.api.Assertions.assertThat; + +@DomainModel( + annotatedClasses = { + SetAndBagCollectionTest.Customer.class, + SetAndBagCollectionTest.Order.class, + SetAndBagCollectionTest.Item.class, + } +) +@SessionFactory +@ServiceRegistry( + settings = { + @Setting(name = AvailableSettings.DEFAULT_BATCH_FETCH_SIZE, value = "10") + } +) +public class SetAndBagCollectionTest { + + @BeforeAll + public void setUp(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Customer customer = new Customer( 1, "First" ); + Order order1 = new Order( 1, "First Order" ); + Order order2 = new Order( 2, "Second Order" ); + + customer.addOrder( order1 ); + customer.addOrder( order2 ); + + Item item1 = new Item( 1, "first" ); + Item item2 = new Item( 2, "second" ); + Item item3 = new Item( 3, "third" ); + + order1.addItem( item1 ); + order1.addItem( item2 ); + order1.addItem( item3 ); + order1.addItem( item3 ); + + Item item4 = new Item( 4, "fourth" ); + Item item5 = new Item( 5, "fifth" ); + + order2.addItem( item4 ); + order2.addItem( item5 ); + + session.persist( item1 ); + session.persist( item2 ); + session.persist( item3 ); + session.persist( item4 ); + session.persist( item5 ); + + session.persist( order1 ); + session.persist( order2 ); + + session.persist( customer ); + } + ); + } + + @Test + public void testThatRetrievedBagElementsAreofTheRightCardinality(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Customer customer = session.get( Customer.class, 1 ); + Set orders = customer.getOrders(); + + assertThat( orders.size() ).isEqualTo( 2 ); + + orders.forEach( + order -> { + Collection items = order.getItems(); + if ( order.getId() == 1 ) { + assertThat( items.size() ).isEqualTo( 4 ); + } + else { + assertThat( items.size() ).isEqualTo( 2 ); + } + } + ); + + } + ); + } + + @Entity(name = "Customer") + public static class Customer { + @Id + public Integer id; + + public String name; + + @OneToMany + Set orders = new HashSet<>(); + + public Customer() { + } + + public Customer(int id, String name) { + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + + public Set getOrders() { + return orders; + } + + public void addOrder(Order order) { + orders.add( order ); + } + } + + @Entity(name = "Order") + @Table(name = "ORDER_TABLE") + public static class Order { + @Id + public Integer id; + + public String description; + + @ManyToMany(fetch = FetchType.EAGER) + Collection items = new ArrayList<>(); + + public Order() { + } + + public Order(Integer id, String description) { + this.id = id; + this.description = description; + } + + public Integer getId() { + return id; + } + + public String getDescription() { + return description; + } + + public Collection getItems() { + return items; + } + + public void addItem(Item item) { + items.add( item ); + item.orders.add( this); + } + } + + @Entity(name = "Item") + @Table(name = "ITEM_TABLE") + public static class Item { + @Id + public Integer id; + + public String description; + + @ManyToMany(mappedBy = "items") + public Collection orders = new ArrayList<>(); + + public Item() { + } + + public Item(Integer id, String description) { + this.id = id; + this.description = description; + } + + public Integer getId() { + return id; + } + + public String getDescription() { + return description; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/SetAndBagCollectionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/SetAndBagCollectionTest.java new file mode 100644 index 0000000000..dade05b57f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/SetAndBagCollectionTest.java @@ -0,0 +1,197 @@ +package org.hibernate.orm.test.collection; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +import static org.assertj.core.api.Assertions.assertThat; + +@DomainModel( + annotatedClasses = { + SetAndBagCollectionTest.Customer.class, + SetAndBagCollectionTest.Order.class, + SetAndBagCollectionTest.Item.class, + } +) +@SessionFactory +public class SetAndBagCollectionTest { + + @BeforeAll + public void setUp(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Customer customer = new Customer( 1, "First" ); + Order order1 = new Order( 1, "First Order" ); + Order order2 = new Order( 2, "Second Order" ); + + customer.addOrder( order1 ); + customer.addOrder( order2 ); + + Item item1 = new Item( 1, "first" ); + Item item2 = new Item( 2, "second" ); + Item item3 = new Item( 3, "third" ); + + order1.addItem( item1 ); + order1.addItem( item2 ); + order1.addItem( item3 ); + order1.addItem( item3 ); + + Item item4 = new Item( 4, "fourth" ); + Item item5 = new Item( 5, "fifth" ); + + order2.addItem( item4 ); + order2.addItem( item5 ); + + session.persist( item1 ); + session.persist( item2 ); + session.persist( item3 ); + session.persist( item4 ); + session.persist( item5 ); + + session.persist( order1 ); + session.persist( order2 ); + + session.persist( customer ); + } + ); + } + + @Test + public void testThatRetrievedBagElementsAreofTheRightCardinality(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Customer customer = session.get( Customer.class, 1 ); + Set orders = customer.getOrders(); + + assertThat( orders.size() ).isEqualTo( 2 ); + + orders.forEach( + order -> { + Collection items = order.getItems(); + if ( order.getId() == 1 ) { + assertThat( items.size() ).isEqualTo( 4 ); + } + else { + assertThat( items.size() ).isEqualTo( 2 ); + } + } + ); + + } + ); + } + + @Entity(name = "Customer") + public static class Customer { + @Id + public Integer id; + + public String name; + + @OneToMany + Set orders = new HashSet<>(); + + public Customer() { + } + + public Customer(int id, String name) { + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + + public Set getOrders() { + return orders; + } + + public void addOrder(Order order) { + orders.add( order ); + } + } + + @Entity(name = "Order") + @Table(name = "ORDER_TABLE") + public static class Order { + @Id + public Integer id; + + public String description; + + @ManyToMany(fetch = FetchType.EAGER) + Collection items = new ArrayList<>(); + + public Order() { + } + + public Order(Integer id, String description) { + this.id = id; + this.description = description; + } + + public Integer getId() { + return id; + } + + public String getDescription() { + return description; + } + + public Collection getItems() { + return items; + } + + public void addItem(Item item) { + items.add( item ); + item.orders.add( this); + } + } + + @Entity(name = "Item") + @Table(name = "ITEM_TABLE") + public static class Item { + @Id + public Integer id; + + public String description; + + @ManyToMany(mappedBy = "items") + public Collection orders = new ArrayList<>(); + + public Item() { + } + + public Item(Integer id, String description) { + this.id = id; + this.description = description; + } + + public Integer getId() { + return id; + } + + public String getDescription() { + return description; + } + } +}