diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java index 5cfc259043..acfd030598 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java @@ -27,6 +27,9 @@ import org.hibernate.test.bytecode.enhancement.lazy.basic.LazyBasicFieldAccessTe import org.hibernate.test.bytecode.enhancement.lazy.basic.LazyBasicPropertyAccessTestTask; import org.hibernate.test.bytecode.enhancement.merge.CompositeMergeTestTask; import org.hibernate.test.bytecode.enhancement.pk.EmbeddedPKTestTask; +import org.hibernate.test.bytecode.enhancement.ondemandload.LazyCollectionWithClearedSessionTestTask; +import org.hibernate.test.bytecode.enhancement.ondemandload.LazyCollectionWithClosedSessionTestTask; +import org.hibernate.test.bytecode.enhancement.ondemandload.LazyEntityLoadingWithClosedSessionTestTask; import org.junit.Test; /** @@ -60,6 +63,15 @@ public class EnhancerTest extends BaseUnitTestCase { EnhancerTestUtils.runEnhancerTestTask( LazyBasicFieldAccessTestTask.class ); } + @Test + @TestForIssue( jiraKey = "HHH-10055" ) + @FailureExpected( jiraKey = "HHH-10055" ) + public void testOnDemand() { + EnhancerTestUtils.runEnhancerTestTask( LazyCollectionWithClearedSessionTestTask.class ); + EnhancerTestUtils.runEnhancerTestTask( LazyCollectionWithClosedSessionTestTask.class ); + EnhancerTestUtils.runEnhancerTestTask( LazyEntityLoadingWithClosedSessionTestTask.class ); + } + @Test public void testMerge() { EnhancerTestUtils.runEnhancerTestTask( CompositeMergeTestTask.class ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Inventory.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Inventory.java new file mode 100644 index 0000000000..adff327276 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Inventory.java @@ -0,0 +1,84 @@ +/* + * 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 . + */ +package org.hibernate.test.bytecode.enhancement.ondemandload; + +import java.math.BigDecimal; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import org.hibernate.annotations.GenericGenerator; + +@Entity +public class Inventory { + private int id = -1; + private Store store; + private Product product; + private Long quantity; + private BigDecimal storePrice; + + public Inventory() { + } + + public Inventory(Store store, Product product) { + this.store = store; + this.product = product; + } + + @Id + @GeneratedValue + @GenericGenerator( name = "increment", strategy = "increment" ) + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @ManyToOne + @JoinColumn( name = "store_id" ) + public Store getStore() { + return store; + } + + public Inventory setStore(Store store) { + this.store = store; + return this; + } + + @ManyToOne + @JoinColumn( name = "prod_id" ) + public Product getProduct() { + return product; + } + + public Inventory setProduct(Product product) { + this.product = product; + return this; + } + + public Long getQuantity() { + return quantity; + } + + public Inventory setQuantity(Long quantity) { + this.quantity = quantity; + return this; + } + + public BigDecimal getStorePrice() { + return storePrice; + } + + public Inventory setStorePrice(BigDecimal storePrice) { + this.storePrice = storePrice; + return this; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyCollectionWithClearedSessionTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyCollectionWithClearedSessionTestTask.java new file mode 100644 index 0000000000..a97e441e0b --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyCollectionWithClearedSessionTestTask.java @@ -0,0 +1,103 @@ +/* + * 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 . + */ + +package org.hibernate.test.bytecode.enhancement.ondemandload; + +import java.math.BigDecimal; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; + +import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class LazyCollectionWithClearedSessionTestTask extends AbstractEnhancerTestTask { + + public void prepare() { + Configuration cfg = new Configuration(); + cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" ); + cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + super.prepare( cfg ); + + Session s = getFactory().openSession(); + s.beginTransaction(); + + Store store = new Store( 1 ).setName( "Acme Super Outlet" ); + s.persist( store ); + + Product product = new Product( "007" ).setName( "widget" ).setDescription( "FooBar" ); + s.persist( product ); + + store.addInventoryProduct( product ).setQuantity( 10L ).setStorePrice( new BigDecimal( 500 ) ); + + s.getTransaction().commit(); + s.close(); + } + + public void cleanup() { + } + + public void execute() { + getFactory().getStatistics().clear(); + + Session s = getFactory().openSession(); + s.beginTransaction(); + + // first load the store, making sure collection is not initialized + Store store = s.get( Store.class, 1 ); + assertNotNull( store ); + assertFalse( Hibernate.isInitialized( store.getInventories() ) ); + + assertEquals( 1, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 0, getFactory().getStatistics().getSessionCloseCount() ); + + // then clear session and try to initialize collection + s.clear(); + store.getInventories().size(); + assertTrue( Hibernate.isInitialized( store.getInventories() ) ); + + assertEquals( 2, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 1, getFactory().getStatistics().getSessionCloseCount() ); + + s.clear(); + store = s.get( Store.class, 1 ); + assertNotNull( store ); + assertFalse( Hibernate.isInitialized( store.getInventories() ) ); + + assertEquals( 2, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 1, getFactory().getStatistics().getSessionCloseCount() ); + + s.clear(); + store.getInventories().iterator(); + assertTrue( Hibernate.isInitialized( store.getInventories() ) ); + + assertEquals( 3, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 2, getFactory().getStatistics().getSessionCloseCount() ); + + s.getTransaction().commit(); + s.close(); + } + + protected void configure(Configuration cfg) { + } + + public Class[] getAnnotatedClasses() { + return new Class[] { + Store.class, + Inventory.class, + Product.class + }; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyCollectionWithClosedSessionTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyCollectionWithClosedSessionTestTask.java new file mode 100644 index 0000000000..6545ec28a1 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyCollectionWithClosedSessionTestTask.java @@ -0,0 +1,91 @@ +/* + * 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 . + */ + +package org.hibernate.test.bytecode.enhancement.ondemandload; + +import java.math.BigDecimal; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; + +import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class LazyCollectionWithClosedSessionTestTask extends AbstractEnhancerTestTask { + + public void prepare() { + Configuration cfg = new Configuration(); + cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" ); + cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + super.prepare( cfg ); + + + Session s = getFactory().openSession(); + s.beginTransaction(); + + Store store = new Store( 1 ).setName( "Acme Super Outlet" ); + s.persist( store ); + + Product product = new Product( "007" ).setName( "widget" ).setDescription( "FooBar" ); + s.persist( product ); + + store.addInventoryProduct( product ).setQuantity( 10L ).setStorePrice( new BigDecimal( 500 ) ); + + s.getTransaction().commit(); + s.close(); + } + + public void cleanup() { + } + + public void execute() { + getFactory().getStatistics().clear(); + + Session s = getFactory().openSession(); + s.beginTransaction(); + + // first load the store, making sure collection is not initialized + Store store = s.get( Store.class, 1 ); + assertNotNull( store ); + assertFalse( Hibernate.isInitialized( store.getInventories() ) ); + + assertEquals( 1, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 0, getFactory().getStatistics().getSessionCloseCount() ); + + // close the session and try to initialize collection + s.getTransaction().commit(); + s.close(); + + assertEquals( 1, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 1, getFactory().getStatistics().getSessionCloseCount() ); + + store.getInventories().size(); + assertTrue( Hibernate.isInitialized( store.getInventories() ) ); + + assertEquals( 2, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 2, getFactory().getStatistics().getSessionCloseCount() ); + } + + protected void configure(Configuration cfg) { + } + + public Class[] getAnnotatedClasses() { + return new Class[] { + Store.class, + Inventory.class, + Product.class + }; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyEntityLoadingWithClosedSessionTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyEntityLoadingWithClosedSessionTestTask.java new file mode 100644 index 0000000000..b0109a9534 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/LazyEntityLoadingWithClosedSessionTestTask.java @@ -0,0 +1,90 @@ +/* + * 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 . + */ + +package org.hibernate.test.bytecode.enhancement.ondemandload; + +import java.math.BigDecimal; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; + +import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class LazyEntityLoadingWithClosedSessionTestTask extends AbstractEnhancerTestTask { + + public void prepare() { + Configuration cfg = new Configuration(); + cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" ); + cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + super.prepare( cfg ); + + Session s = getFactory().openSession(); + s.beginTransaction(); + + Store store = new Store( 1 ).setName( "Acme Super Outlet" ); + s.persist( store ); + + Product product = new Product( "007" ).setName( "widget" ).setDescription( "FooBar" ); + s.persist( product ); + + store.addInventoryProduct( product ).setQuantity( 10L ).setStorePrice( new BigDecimal( 500 ) ); + + s.getTransaction().commit(); + s.close(); + } + + public void cleanup() { + } + + public void execute() { + getFactory().getStatistics().clear(); + + Session s = getFactory().openSession(); + s.beginTransaction(); + + // first load the store, making sure it is not initialized + Store store = s.load( Store.class, 1 ); + assertNotNull( store ); + assertFalse( Hibernate.isInitialized( store ) ); + + assertEquals( 1, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 0, getFactory().getStatistics().getSessionCloseCount() ); + + // close the session and try to initialize store + s.getTransaction().commit(); + s.close(); + + assertEquals( 1, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 1, getFactory().getStatistics().getSessionCloseCount() ); + + store.getName(); + assertTrue( Hibernate.isInitialized( store ) ); + + assertEquals( 2, getFactory().getStatistics().getSessionOpenCount() ); + assertEquals( 2, getFactory().getStatistics().getSessionCloseCount() ); + } + + protected void configure(Configuration cfg) { + } + + public Class[] getAnnotatedClasses() { + return new Class[] { + Store.class, + Inventory.class, + Product.class + }; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Product.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Product.java new file mode 100644 index 0000000000..990024ac01 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Product.java @@ -0,0 +1,74 @@ +/* + * 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 . + */ +package org.hibernate.test.bytecode.enhancement.ondemandload; + +import java.io.Serializable; +import java.math.BigDecimal; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Version; + +@Entity +public class Product implements Serializable { + private String id; + private String name; + private String description; + private BigDecimal msrp; + private int version; + + private Product() { + } + + public Product(String id) { + this.id = id; + } + + @Id + public String getId() { + return id; + } + + private void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public Product setName(String name) { + this.name = name; + return this; + } + + public String getDescription() { + return description; + } + + public Product setDescription(String description) { + this.description = description; + return this; + } + + public BigDecimal getMsrp() { + return msrp; + } + + public Product setMsrp(BigDecimal msrp) { + this.msrp = msrp; + return this; + } + + @Version + public int getVersion() { + return version; + } + + private void setVersion(int version) { + this.version = version; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Store.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Store.java new file mode 100644 index 0000000000..98487cbf7f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/ondemandload/Store.java @@ -0,0 +1,77 @@ +/* + * 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 . + */ +package org.hibernate.test.bytecode.enhancement.ondemandload; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Version; + +@Entity +public class Store implements Serializable { + private int id; + private String name; + private List inventories = new ArrayList(); + private int version; + + protected Store() { + } + + public Store(int id) { + this.id = id; + } + + @Id + @Column(name = "ID") + public Integer getId() { + return id; + } + + private void setId(int id) { + this.id = id; + } + + @Column(name = "NAME") + public String getName() { + return name; + } + + public Store setName(String name) { + this.name = name; + return this; + } + + @OneToMany(mappedBy = "store", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public Inventory addInventoryProduct(Product product) { + final Inventory inventory = new Inventory( this, product ); + this.inventories.add( inventory ); + return inventory; + } + + @Version + public int getVersion() { + return version; + } + + private void setVersion(int version) { + this.version = version; + } +}