Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HHH-12687 : ManyToOne associations in embeddable collection elements …
…and composite IDs are always eagerly loaded (cherry picked from commit 607e516)
- Loading branch information
Showing
5 changed files
with
338 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
165 changes: 165 additions & 0 deletions
165
.../test/annotations/collectionelement/EmbeddableCollectionElementWithLazyManyToOneTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. | ||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. | ||
*/ | ||
package org.hibernate.test.annotations.collectionelement; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
import javax.persistence.CascadeType; | ||
import javax.persistence.ElementCollection; | ||
import javax.persistence.Embeddable; | ||
import javax.persistence.Entity; | ||
import javax.persistence.FetchType; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.Id; | ||
import javax.persistence.ManyToOne; | ||
|
||
import org.hibernate.Hibernate; | ||
|
||
import org.hibernate.testing.TestForIssue; | ||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; | ||
import org.junit.Test; | ||
|
||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
/** | ||
* @author Gail Badner | ||
*/ | ||
public class EmbeddableCollectionElementWithLazyManyToOneTest extends BaseCoreFunctionalTestCase { | ||
|
||
@Override | ||
protected Class[] getAnnotatedClasses() { | ||
return new Class[] { | ||
Parent.class, | ||
Child.class | ||
}; | ||
} | ||
|
||
@Test | ||
@TestForIssue( jiraKey = "???") | ||
public void testLazyManyToOneInEmbeddable() { | ||
Parent p = new Parent(); | ||
p.containedChild = new ContainedChild( new Child() ); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
session.persist( p ); | ||
} | ||
); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
Parent pRead = session.get( Parent.class, p.id ); | ||
assertFalse( Hibernate.isInitialized( pRead.containedChild.child ) ); | ||
} | ||
); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
session.delete( p ); | ||
} | ||
); | ||
} | ||
|
||
@Test | ||
@TestForIssue( jiraKey = "???") | ||
public void testLazyManyToOneInCollectionElementEmbeddable() { | ||
Parent p = new Parent(); | ||
p.containedChildren.add( new ContainedChild( new Child() ) ); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
session.persist( p ); | ||
} | ||
); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
Parent pRead = session.get( Parent.class, p.id ); | ||
assertFalse( Hibernate.isInitialized( pRead.containedChildren ) ); | ||
assertEquals( 1, pRead.containedChildren.size() ); | ||
assertTrue( Hibernate.isInitialized( pRead.containedChildren ) ); | ||
assertFalse( Hibernate.isInitialized( pRead.containedChildren.iterator().next().child ) ); | ||
} | ||
); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
session.delete( p ); | ||
} | ||
); | ||
} | ||
|
||
@Test | ||
@TestForIssue( jiraKey = "???") | ||
public void testLazyBoth() { | ||
Parent p = new Parent(); | ||
ContainedChild containedChild = new ContainedChild( new Child() ); | ||
p.containedChild = containedChild; | ||
p.containedChildren.add( containedChild ); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
session.persist( p ); | ||
} | ||
); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
Parent pRead = session.get( Parent.class, p.id ); | ||
assertFalse( Hibernate.isInitialized( pRead.containedChild.child ) ); | ||
assertFalse( Hibernate.isInitialized( pRead.containedChildren ) ); | ||
assertEquals( 1, pRead.containedChildren.size() ); | ||
assertTrue( Hibernate.isInitialized( pRead.containedChildren ) ); | ||
assertFalse( Hibernate.isInitialized( pRead.containedChildren.iterator().next().child ) ); | ||
} | ||
); | ||
|
||
doInHibernate( | ||
this::sessionFactory, session -> { | ||
session.delete( p ); | ||
} | ||
); | ||
} | ||
|
||
@Entity(name = "Parent") | ||
public static class Parent { | ||
@Id | ||
@GeneratedValue | ||
private int id; | ||
|
||
private ContainedChild containedChild; | ||
|
||
@ElementCollection | ||
private Set<ContainedChild> containedChildren = new HashSet<ContainedChild>(); | ||
} | ||
|
||
@Entity(name = "Child") | ||
public static class Child { | ||
@Id | ||
@GeneratedValue | ||
private int id; | ||
|
||
} | ||
|
||
@Embeddable | ||
public static class ContainedChild { | ||
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) | ||
private Child child; | ||
|
||
ContainedChild() { | ||
} | ||
|
||
ContainedChild(Child child) { | ||
this.child = child; | ||
} | ||
} | ||
|
||
|
||
} |
48 changes: 48 additions & 0 deletions
48
...ibernate/test/keymanytoone/bidir/component/EagerCollectionLazyKeyManyToOneMapping.hbm.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?xml version="1.0"?> | ||
<!-- | ||
~ Hibernate, Relational Persistence for Idiomatic Java | ||
~ | ||
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later. | ||
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. | ||
--> | ||
<!DOCTYPE hibernate-mapping PUBLIC | ||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" | ||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> | ||
|
||
<!-- | ||
This mapping demonstrates the use of composite ids with the | ||
key-many-to-one feature. Essentially a composite id where part | ||
of the composition is a foreign-key to another entity. | ||
Here, specifically, we map the key-many-to-one as a lazy | ||
association. | ||
--> | ||
|
||
<hibernate-mapping package="org.hibernate.test.keymanytoone.bidir.component"> | ||
|
||
<class name="Customer" table="COMP_LAZY_KM2O_CUST"> | ||
<id name="id" column="ID" type="long"> | ||
<generator class="increment" /> | ||
</id> | ||
<property name="name" column="NAME" type="string" /> | ||
<bag name="orders" inverse="true" cascade="all" lazy="false" fetch="join"> | ||
<key column="CUST_ID" /> | ||
<one-to-many class="Order" /> | ||
</bag> | ||
</class> | ||
|
||
<class name="Order" table="COMP_LAZY_KM2O_ORDR"> | ||
<composite-id name="id" class="Order$Id"> | ||
<key-many-to-one name="customer" class="Customer" column="CUST_ID" lazy="proxy"/> | ||
<key-property name="number" column="ORDR_NUM" type="long" /> | ||
</composite-id> | ||
<set name="items" table="COMP_LAZY_KM2O_ITEM"> | ||
<key> | ||
<column name="CUST_ID"/> | ||
<column name="ORDER_NUM"/> | ||
</key> | ||
<element type="string" column="ITEM_DESC" /> | ||
</set> | ||
</class> | ||
|
||
</hibernate-mapping> |
110 changes: 110 additions & 0 deletions
110
.../org/hibernate/test/keymanytoone/bidir/component/EagerCollectionLazyKeyManyToOneTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. | ||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. | ||
*/ | ||
package org.hibernate.test.keymanytoone.bidir.component; | ||
|
||
import java.util.List; | ||
|
||
import org.hibernate.Session; | ||
import org.hibernate.cfg.Configuration; | ||
import org.hibernate.cfg.Environment; | ||
|
||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; | ||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
/** | ||
* @author Steve Ebersole | ||
*/ | ||
public class EagerCollectionLazyKeyManyToOneTest extends BaseCoreFunctionalTestCase { | ||
@Override | ||
public String[] getMappings() { | ||
return new String[] { "keymanytoone/bidir/component/EagerCollectionLazyKeyManyToOneMapping.hbm.xml" }; | ||
} | ||
|
||
@Override | ||
public void configure(Configuration cfg) { | ||
super.configure( cfg ); | ||
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); | ||
} | ||
|
||
@Test | ||
public void testQueryingOnMany2One() { | ||
Session s = openSession(); | ||
s.beginTransaction(); | ||
Customer cust = new Customer( "Acme, Inc." ); | ||
Order order = new Order( new Order.Id( cust, 1 ) ); | ||
cust.getOrders().add( order ); | ||
s.save( cust ); | ||
s.getTransaction().commit(); | ||
s.close(); | ||
|
||
s = openSession(); | ||
s.beginTransaction(); | ||
List results = s.createQuery( "from Order o where o.id.customer.name = :name" ) | ||
.setParameter( "name", cust.getName() ) | ||
.list(); | ||
assertEquals( 1, results.size() ); | ||
s.getTransaction().commit(); | ||
s.close(); | ||
|
||
s = openSession(); | ||
s.beginTransaction(); | ||
s.delete( cust ); | ||
s.getTransaction().commit(); | ||
s.close(); | ||
} | ||
|
||
@Test | ||
public void testSaveCascadedToKeyManyToOne() { | ||
// test cascading a save to an association with a key-many-to-one which refers to a | ||
// just saved entity | ||
Session s = openSession(); | ||
s.beginTransaction(); | ||
Customer cust = new Customer( "Acme, Inc." ); | ||
Order order = new Order( new Order.Id( cust, 1 ) ); | ||
cust.getOrders().add( order ); | ||
sessionFactory().getStatistics().clear(); | ||
s.save( cust ); | ||
s.flush(); | ||
assertEquals( 2, sessionFactory().getStatistics().getEntityInsertCount() ); | ||
s.delete( cust ); | ||
s.getTransaction().commit(); | ||
s.close(); | ||
} | ||
|
||
@Test | ||
public void testLoadingStrategies() { | ||
Session s = openSession(); | ||
s.beginTransaction(); | ||
Customer cust = new Customer( "Acme, Inc." ); | ||
Order order = new Order( new Order.Id( cust, 1 ) ); | ||
cust.getOrders().add( order ); | ||
s.save( cust ); | ||
s.getTransaction().commit(); | ||
s.close(); | ||
|
||
s = openSession(); | ||
s.beginTransaction(); | ||
|
||
cust = ( Customer ) s.get( Customer.class, cust.getId() ); | ||
assertEquals( 1, cust.getOrders().size() ); | ||
s.clear(); | ||
|
||
cust = ( Customer ) s.createQuery( "from Customer" ).uniqueResult(); | ||
assertEquals( 1, cust.getOrders().size() ); | ||
s.clear(); | ||
|
||
cust = ( Customer ) s.createQuery( "from Customer c join fetch c.orders" ).uniqueResult(); | ||
assertEquals( 1, cust.getOrders().size() ); | ||
s.clear(); | ||
|
||
s.delete( cust ); | ||
s.getTransaction().commit(); | ||
s.close(); | ||
} | ||
} |