[hibernate-commits] Hibernate SVN: r14102 - in core/branches/Branch_3_2: test/org/hibernate/test/generated and 4 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Thu Oct 18 18:28:23 EDT 2007
Author: gbadner
Date: 2007-10-18 18:28:23 -0400 (Thu, 18 Oct 2007)
New Revision: 14102
Added:
core/branches/Branch_3_2/test/org/hibernate/test/instrument/cases/TestSharedPKOneToOneExecutable.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/EntityWithOneToOnes.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/OneToOneNoProxy.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/OneToOneProxy.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/SharedPKOneToOne.hbm.xml
Modified:
core/branches/Branch_3_2/src/org/hibernate/persister/entity/AbstractEntityPersister.java
core/branches/Branch_3_2/test/org/hibernate/test/generated/AbstractGeneratedPropertyTest.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/cases/TestLazyExecutable.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/AbstractTransformingClassLoaderInstrumentTestCase.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/CGLIBInstrumentationTest.java
core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/JavassistInstrumentationTest.java
Log:
HHH-2627 : Generated and lazy properties leak prepared statements
Modified: core/branches/Branch_3_2/src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2007-10-18 20:08:50 UTC (rev 14101)
+++ core/branches/Branch_3_2/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -776,31 +776,35 @@
Object result = null;
PreparedStatement ps = null;
- ResultSet rs = null;
try {
final String lazySelect = getSQLLazySelectString();
- if ( lazySelect != null ) {
- // null sql means that the only lazy properties
- // are shared PK one-to-one associations which are
- // handled differently in the Type#nullSafeGet code...
- ps = session.getBatcher().prepareSelectStatement(lazySelect);
- getIdentifierType().nullSafeSet( ps, id, 1, session );
- rs = session.getBatcher().getResultSet( ps );
- rs.next();
+ ResultSet rs = null;
+ try {
+ if ( lazySelect != null ) {
+ // null sql means that the only lazy properties
+ // are shared PK one-to-one associations which are
+ // handled differently in the Type#nullSafeGet code...
+ ps = session.getBatcher().prepareSelectStatement(lazySelect);
+ getIdentifierType().nullSafeSet( ps, id, 1, session );
+ rs = ps.executeQuery();
+ rs.next();
+ }
+ final Object[] snapshot = entry.getLoadedState();
+ for ( int j = 0; j < lazyPropertyNames.length; j++ ) {
+ Object propValue = lazyPropertyTypes[j].nullSafeGet( rs, lazyPropertyColumnAliases[j], session, entity );
+ if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) {
+ result = propValue;
+ }
+ }
}
- final Object[] snapshot = entry.getLoadedState();
- for ( int j = 0; j < lazyPropertyNames.length; j++ ) {
- Object propValue = lazyPropertyTypes[j].nullSafeGet( rs, lazyPropertyColumnAliases[j], session, entity );
- if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) {
- result = propValue;
+ finally {
+ if ( rs != null ) {
+ rs.close();
}
}
}
finally {
- if ( rs != null ) {
- session.getBatcher().closeQueryStatement( ps, rs );
- }
- else if ( ps != null ) {
+ if ( ps != null ) {
session.getBatcher().closeStatement( ps );
}
}
@@ -3695,26 +3699,32 @@
try {
PreparedStatement ps = session.getBatcher().prepareSelectStatement( selectionSQL );
- ResultSet rs = null;
try {
getIdentifierType().nullSafeSet( ps, id, 1, session );
- rs = session.getBatcher().getResultSet( ps );
- if ( !rs.next() ) {
- throw new HibernateException(
- "Unable to locate row for retrieval of generated properties: " +
- MessageHelper.infoString( this, id, getFactory() )
- );
+ ResultSet rs = ps.executeQuery();
+ try {
+ if ( !rs.next() ) {
+ throw new HibernateException(
+ "Unable to locate row for retrieval of generated properties: " +
+ MessageHelper.infoString( this, id, getFactory() )
+ );
+ }
+ for ( int i = 0; i < getPropertySpan(); i++ ) {
+ if ( includeds[i] != ValueInclusion.NONE ) {
+ Object hydratedState = getPropertyTypes()[i].hydrate( rs, getPropertyAliases( "", i ), session, entity );
+ state[i] = getPropertyTypes()[i].resolve( hydratedState, session, entity );
+ setPropertyValue( entity, i, state[i], session.getEntityMode() );
+ }
+ }
}
- for ( int i = 0; i < getPropertySpan(); i++ ) {
- if ( includeds[i] != ValueInclusion.NONE ) {
- Object hydratedState = getPropertyTypes()[i].hydrate( rs, getPropertyAliases( "", i ), session, entity );
- state[i] = getPropertyTypes()[i].resolve( hydratedState, session, entity );
- setPropertyValue( entity, i, state[i], session.getEntityMode() );
+ finally {
+ if ( rs != null ) {
+ rs.close();
}
}
}
finally {
- session.getBatcher().closeQueryStatement( ps, rs );
+ session.getBatcher().closeStatement( ps );
}
}
catch( SQLException sqle ) {
Modified: core/branches/Branch_3_2/test/org/hibernate/test/generated/AbstractGeneratedPropertyTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/generated/AbstractGeneratedPropertyTest.java 2007-10-18 20:08:50 UTC (rev 14101)
+++ core/branches/Branch_3_2/test/org/hibernate/test/generated/AbstractGeneratedPropertyTest.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -17,6 +17,13 @@
}
public final void testGeneratedProperty() {
+ // The following block is repeated 300 times to reproduce HHH-2627.
+ // Without the fix, Oracle will run out of cursors using 10g with
+ // a default installation (ORA-01000: maximum open cursors exceeded).
+ // The number of loops may need to be adjusted depending on the how
+ // Oracle is configured.
+ // Note: The block is not indented to avoid a lot of irrelevant differences.
+ for ( int i=0; i<300; i++ ) {
GeneratedPropertyEntity entity = new GeneratedPropertyEntity();
entity.setName( "entity-1" );
Session s = openSession();
@@ -43,5 +50,6 @@
s.delete( entity );
t.commit();
s.close();
+ }
}
}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java 2007-10-18 20:08:50 UTC (rev 14101)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/buildtime/InstrumentTest.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -14,6 +14,7 @@
import org.hibernate.test.instrument.cases.TestIsPropertyInitializedExecutable;
import org.hibernate.test.instrument.cases.TestLazyPropertyCustomTypeExecutable;
import org.hibernate.test.instrument.cases.TestManyToOneProxyExecutable;
+import org.hibernate.test.instrument.cases.TestSharedPKOneToOneExecutable;
import org.hibernate.test.instrument.cases.Executable;
import org.hibernate.junit.UnitTestCase;
@@ -62,6 +63,10 @@
execute( new TestLazyPropertyCustomTypeExecutable() );
}
+ public void testSharedPKOneToOne() {
+ execute( new TestSharedPKOneToOneExecutable() );
+ }
+
private void execute(Executable executable) {
executable.prepare();
try {
Modified: core/branches/Branch_3_2/test/org/hibernate/test/instrument/cases/TestLazyExecutable.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/cases/TestLazyExecutable.java 2007-10-18 20:08:50 UTC (rev 14101)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/cases/TestLazyExecutable.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -17,6 +17,14 @@
*/
public class TestLazyExecutable extends AbstractExecutable {
public void execute() {
+ // The following block is repeated 100 times to reproduce HHH-2627.
+ // Without the fix, Oracle will run out of cursors using 10g with
+ // a default installation (ORA-01000: maximum open cursors exceeded).
+ // The number of loops may need to be adjusted depending on the how
+ // Oracle is configured.
+ // Note: The block is not indented to avoid a lot of irrelevant differences.
+ for ( int i=0; i<100; i++ ) {
+
SessionFactory factory = getFactory();
Session s = factory.openSession();
Transaction t = s.beginTransaction();
@@ -192,6 +200,9 @@
s.flush();
t.commit();
s.close();
+
+ }
+
}
}
Added: core/branches/Branch_3_2/test/org/hibernate/test/instrument/cases/TestSharedPKOneToOneExecutable.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/cases/TestSharedPKOneToOneExecutable.java (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/cases/TestSharedPKOneToOneExecutable.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -0,0 +1,69 @@
+package org.hibernate.test.instrument.cases;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.Hibernate;
+import org.hibernate.test.instrument.domain.EntityWithOneToOnes;
+import org.hibernate.test.instrument.domain.OneToOneProxy;
+import org.hibernate.test.instrument.domain.OneToOneNoProxy;
+import junit.framework.Assert;
+
+/**
+ *
+ * @author Gail Badner
+ */
+public class TestSharedPKOneToOneExecutable extends AbstractExecutable {
+
+ protected String[] getResources() {
+ return new String[] {"org/hibernate/test/instrument/domain/SharedPKOneToOne.hbm.xml"};
+ }
+
+ public void execute() {
+ Session s = getFactory().openSession();
+ Transaction t = s.beginTransaction();
+ EntityWithOneToOnes root = new EntityWithOneToOnes( "root" );
+ OneToOneProxy oneToOneProxy = new OneToOneProxy( "oneToOneProxy" );
+ root.setOneToOneProxy( oneToOneProxy );
+ oneToOneProxy.setEntity( root );
+ OneToOneNoProxy oneToOneNoProxy = new OneToOneNoProxy( "oneToOneNoProxy" );
+ root.setOneToOneNoProxy( oneToOneNoProxy );
+ oneToOneNoProxy.setEntity( root );
+
+ s.save( root );
+ t.commit();
+ s.close();
+
+ // NOTE : oneToOneProxy is mapped with lazy="proxy"; oneToOneNoProxy with lazy="no-proxy"...
+
+ s = getFactory().openSession();
+ t = s.beginTransaction();
+ // load root
+ root = ( EntityWithOneToOnes ) s.load( EntityWithOneToOnes.class, root.getId() );
+ Assert.assertFalse( Hibernate.isInitialized( root ) );
+ Assert.assertFalse( Hibernate.isPropertyInitialized( root, "name" ) );
+ Assert.assertFalse( Hibernate.isPropertyInitialized( root, "oneToOneProxy" ) );
+ Assert.assertFalse( Hibernate.isPropertyInitialized( root, "oneToOneNoProxy" ) );
+
+ root.getName();
+ Assert.assertTrue( Hibernate.isInitialized( root ) );
+ Assert.assertTrue( Hibernate.isPropertyInitialized( root, "name" ) );
+ Assert.assertTrue( Hibernate.isPropertyInitialized( root, "oneToOneProxy" ) );
+ Assert.assertFalse( Hibernate.isPropertyInitialized( root, "oneToOneNoProxy" ) );
+
+ // get a handle to the oneToOneProxy proxy reference (and make certain that
+ // this does not force the lazy properties of the root entity
+ // to get initialized.
+ root.getOneToOneProxy();
+ Assert.assertTrue( Hibernate.isInitialized( oneToOneProxy ) );
+ Assert.assertTrue( Hibernate.isPropertyInitialized( root.getOneToOneProxy(), "name" ) );
+ Assert.assertFalse( Hibernate.isPropertyInitialized( root, "oneToOneNoProxy" ) );
+
+ root.getOneToOneNoProxy();
+ Assert.assertTrue( Hibernate.isPropertyInitialized( root, "oneToOneNoProxy" ) );
+ Assert.assertTrue( Hibernate.isPropertyInitialized( root.getOneToOneNoProxy(), "name") );
+
+ s.delete( root );
+ t.commit();
+ s.close();
+ }
+}
Added: core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/EntityWithOneToOnes.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/EntityWithOneToOnes.java (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/EntityWithOneToOnes.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -0,0 +1,50 @@
+package org.hibernate.test.instrument.domain;
+
+/**
+ * @author Gail Badner
+ */
+public class EntityWithOneToOnes {
+ private Long id;
+ private String name;
+ private OneToOneNoProxy oneToOneNoProxy;
+ private OneToOneProxy oneToOneProxy;
+
+ public EntityWithOneToOnes() {
+ }
+
+ public EntityWithOneToOnes(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public OneToOneNoProxy getOneToOneNoProxy() {
+ return oneToOneNoProxy;
+ }
+
+ public void setOneToOneNoProxy(OneToOneNoProxy oneToOneNoProxy) {
+ this.oneToOneNoProxy = oneToOneNoProxy;
+ }
+
+ public OneToOneProxy getOneToOneProxy() {
+ return oneToOneProxy;
+ }
+
+ public void setOneToOneProxy(OneToOneProxy oneToOneProxy) {
+ this.oneToOneProxy = oneToOneProxy;
+ }
+}
Added: core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/OneToOneNoProxy.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/OneToOneNoProxy.java (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/OneToOneNoProxy.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -0,0 +1,45 @@
+package org.hibernate.test.instrument.domain;
+
+/**
+ * @author Gail Badner
+ */
+public class OneToOneNoProxy {
+ private Long entityId;
+ private String name;
+ private EntityWithOneToOnes entity;
+
+ public OneToOneNoProxy() {}
+ public OneToOneNoProxy(String name) {
+ this.name = name;
+ }
+ /**
+ * @return Returns the id.
+ */
+ public Long getEntityId() {
+ return entityId;
+ }
+ /**
+ * @param entityId The id to set.
+ */
+ public void setEntityId(Long entityId) {
+ this.entityId = entityId;
+ }
+ /**
+ * @return Returns the name.
+ */
+ public String getName() {
+ return name;
+ }
+ /**
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ public EntityWithOneToOnes getEntity() {
+ return entity;
+ }
+ public void setEntity(EntityWithOneToOnes entity) {
+ this.entity = entity;
+ }
+}
Added: core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/OneToOneProxy.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/OneToOneProxy.java (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/OneToOneProxy.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -0,0 +1,45 @@
+package org.hibernate.test.instrument.domain;
+
+/**
+ * @author Gail Badner
+ */
+public class OneToOneProxy {
+ private Long entityId;
+ private String name;
+ private EntityWithOneToOnes entity;
+
+ public OneToOneProxy() {}
+ public OneToOneProxy(String name) {
+ this.name = name;
+ }
+ /**
+ * @return Returns the id.
+ */
+ public Long getEntityId() {
+ return entityId;
+ }
+ /**
+ * @param entityId The id to set.
+ */
+ public void setEntityId(Long entityId) {
+ this.entityId = entityId;
+ }
+ /**
+ * @return Returns the name.
+ */
+ public String getName() {
+ return name;
+ }
+ /**
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ public EntityWithOneToOnes getEntity() {
+ return entity;
+ }
+ public void setEntity(EntityWithOneToOnes entity) {
+ this.entity = entity;
+ }
+}
Added: core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/SharedPKOneToOne.hbm.xml
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/SharedPKOneToOne.hbm.xml (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/domain/SharedPKOneToOne.hbm.xml 2007-10-18 22:28:23 UTC (rev 14102)
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ This mapping demonstrates shared PK one-to-one associations using
+ lazy="proxy" and lazy="no-proxy".
+
+ Implementation note: This test does not include any other
+ lazy properties, and allows testing special case code in
+ AbstractEntityPersister.initializeLazyPropertiesFromDatastore()
+ (lazy select string will be null) and OneToOne.nullSafeGet()
+ (ResultSet arg is ignored and the owner's ID is returned).
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.instrument.domain" default-access="field">
+
+ <class name="EntityWithOneToOnes">
+ <id name="id" column="ID" type="long">
+ <generator class="increment"/>
+ </id>
+ <one-to-one name="oneToOneNoProxy" class="OneToOneNoProxy" lazy="no-proxy" cascade="all" />
+ <one-to-one name="oneToOneProxy" class="OneToOneProxy" lazy="proxy" cascade="all" />
+ <property name="name"/>
+ </class>
+
+ <class name="OneToOneNoProxy">
+ <id name="entityId">
+ <generator class="foreign">
+ <param name="property">entity</param>
+ </generator>
+ </id>
+ <one-to-one name="entity" class="EntityWithOneToOnes" constrained="true"/>
+ <property name="name"/>
+ </class>
+
+ <class name="OneToOneProxy">
+ <id name="entityId">
+ <generator class="foreign">
+ <param name="property">entity</param>
+ </generator>
+ </id>
+ <one-to-one name="entity" class="EntityWithOneToOnes" constrained="true"/>
+ <property name="name"/>
+ </class>
+
+
+</hibernate-mapping>
Modified: core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/AbstractTransformingClassLoaderInstrumentTestCase.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/AbstractTransformingClassLoaderInstrumentTestCase.java 2007-10-18 20:08:50 UTC (rev 14101)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/AbstractTransformingClassLoaderInstrumentTestCase.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -78,8 +78,10 @@
executeExecutable( "org.hibernate.test.instrument.cases.TestLazyPropertyCustomTypeExecutable" );
}
+ public void testSharedPKOneToOne() {
+ executeExecutable( "org.hibernate.test.instrument.cases.TestSharedPKOneToOneExecutable" );
+ }
-
// reflection code to ensure isolation into the created classloader ~~~~~~~
private static final Class[] SIG = new Class[] {};
Modified: core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/CGLIBInstrumentationTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/CGLIBInstrumentationTest.java 2007-10-18 20:08:50 UTC (rev 14101)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/CGLIBInstrumentationTest.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -48,4 +48,8 @@
public void testManyToOneProxy() {
super.testManyToOneProxy(); //To change body of overridden methods use File | Settings | File Templates.
}
+
+ public void testSharedPKOneToOne() {
+ super.testSharedPKOneToOne();
+ }
}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/JavassistInstrumentationTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/JavassistInstrumentationTest.java 2007-10-18 20:08:50 UTC (rev 14101)
+++ core/branches/Branch_3_2/test/org/hibernate/test/instrument/runtime/JavassistInstrumentationTest.java 2007-10-18 22:28:23 UTC (rev 14102)
@@ -49,4 +49,8 @@
public void testManyToOneProxy() {
super.testManyToOneProxy();
}
+
+ public void testSharedPKOneToOne() {
+ super.testSharedPKOneToOne();
+ }
}
More information about the hibernate-commits
mailing list