HHH-3220 Patch to prevent org.hibernate.AssertionFailure: possible non-threadsafe access to the session error caused by stateless sessions

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@19518 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Strong Liu 2010-05-15 08:37:30 +00:00
parent dceb92d4a5
commit 6de4dc800f
8 changed files with 239 additions and 2 deletions

View File

@ -445,7 +445,11 @@ public interface PersistenceContext {
* Call this after finishing a two-phase load
*/
public void afterLoad();
/**
* Is in a two-phase load?
*/
public boolean isLoadFinished();
/**
* Returns a string representation of the object.
*

View File

@ -1095,6 +1095,9 @@ public class StatefulPersistenceContext implements PersistenceContext {
loadCounter--;
}
public boolean isLoadFinished() {
return loadCounter == 0;
}
/**
* Returns a string representation of the object.
*

View File

@ -179,7 +179,9 @@ public class StatelessSessionImpl extends AbstractSessionImpl
errorIfClosed();
Object result = getFactory().getEntityPersister(entityName)
.load(id, null, lockMode, this);
temporaryPersistenceContext.clear();
if ( temporaryPersistenceContext.isLoadFinished() ) {
temporaryPersistenceContext.clear();
}
return result;
}

View File

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.stateless">
<class name="Contact">
<id name="id">
<generator class="native" />
</id>
<many-to-one name="org" lazy="false" fetch="join" />
</class>
<class name="Org">
<id name="id">
<generator class="native" />
</id>
<many-to-one name="country" lazy="false" fetch="join" />
</class>
<class name="Country">
<id name="id">
<generator class="native" />
</id>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,47 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.test.stateless;
/**
*
* @author stliu
*/
public class Contact {
private Integer id;
public Integer getId() {
return id;
}
public void setId( Integer id ) {
this.id = id;
}
public Org getOrg() {
return org;
}
public void setOrg( Org org ) {
this.org = org;
}
private Org org;
}

View File

@ -0,0 +1,13 @@
package org.hibernate.test.stateless;
public class Country {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}

View File

@ -0,0 +1,23 @@
package org.hibernate.test.stateless;
public class Org {
private Integer id;
private Country country;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
}

View File

@ -0,0 +1,117 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.test.stateless;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.junit.functional.FunctionalTestCase;
/**
*
* @author stliu
*/
public class StatelessSessionQueryTest extends FunctionalTestCase {
public StatelessSessionQueryTest( String string ) {
super( string );
}
public void testCriteria() {
TestData testData=new TestData();
testData.createData();
StatelessSession s = getSessions().openStatelessSession();
assertEquals( 1, s.createCriteria( Contact.class ).list().size() );
s.close();
testData.cleanData();
}
public void testCriteriaWithSelectFetchMode() {
TestData testData=new TestData();
testData.createData();
StatelessSession s = getSessions().openStatelessSession();
assertEquals( 1, s.createCriteria( Contact.class ).setFetchMode( "org", FetchMode.SELECT )
.list().size() );
s.close();
testData.cleanData();
}
public void testHQL() {
TestData testData=new TestData();
testData.createData();
StatelessSession s = getSessions().openStatelessSession();
assertEquals( 1, s.createQuery( "from Contact c join fetch c.org join fetch c.org.country" )
.list().size() );
s.close();
testData.cleanData();
}
private class TestData{
List list = new ArrayList();
public void createData(){
Session session = openSession();
Transaction tx = session.beginTransaction();
Country usa = new Country();
session.save( usa );
list.add( usa );
Org disney = new Org();
disney.setCountry( usa );
session.save( disney );
list.add( disney );
Contact waltDisney = new Contact();
waltDisney.setOrg( disney );
session.save( waltDisney );
list.add( waltDisney );
tx.commit();
session.close();
}
public void cleanData(){
Session session = openSession();
Transaction tx = session.beginTransaction();
for(Object obj: list){
session.delete( obj );
}
tx.commit();
session.close();
}
}
@Override
public void configure( Configuration cfg ) {
super.configure( cfg );
cfg.setProperty( Environment.MAX_FETCH_DEPTH, "1" );
}
public String[] getMappings() {
return new String[] { "stateless/Contact.hbm.xml" };
}
}