HHH-7971 - Enabling ENABLE_LAZY_LOAD_NO_TRANS results in trying to remove elements in collections
This commit is contained in:
parent
30205607ef
commit
6f342358db
|
@ -35,6 +35,7 @@ import java.util.ListIterator;
|
|||
import javax.naming.NamingException;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LazyInitializationException;
|
||||
import org.hibernate.Session;
|
||||
|
@ -81,7 +82,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
private Serializable storedSnapshot;
|
||||
|
||||
private String sessionFactoryUuid;
|
||||
private boolean specjLazyLoad;
|
||||
private boolean allowLoadOutsideTransaction;
|
||||
|
||||
/**
|
||||
* Not called by Hibernate, but used by non-JDK serialization,
|
||||
|
@ -205,7 +206,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
boolean isJTA = false;
|
||||
|
||||
if ( session == null ) {
|
||||
if ( specjLazyLoad ) {
|
||||
if ( allowLoadOutsideTransaction ) {
|
||||
session = openTemporarySessionForLoading();
|
||||
isTempSession = true;
|
||||
}
|
||||
|
@ -214,7 +215,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
}
|
||||
}
|
||||
else if ( !session.isOpen() ) {
|
||||
if ( specjLazyLoad ) {
|
||||
if ( allowLoadOutsideTransaction ) {
|
||||
originalSession = session;
|
||||
session = openTemporarySessionForLoading();
|
||||
isTempSession = true;
|
||||
|
@ -224,7 +225,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
}
|
||||
}
|
||||
else if ( !session.isConnected() ) {
|
||||
if ( specjLazyLoad ) {
|
||||
if ( allowLoadOutsideTransaction ) {
|
||||
originalSession = session;
|
||||
session = openTemporarySessionForLoading();
|
||||
isTempSession = true;
|
||||
|
@ -235,8 +236,6 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
}
|
||||
|
||||
if ( isTempSession ) {
|
||||
// TODO: On the next major release, add an
|
||||
// 'isJTA' or 'getTransactionFactory' method to Session.
|
||||
isJTA = session.getTransactionCoordinator()
|
||||
.getTransactionContext().getTransactionEnvironment()
|
||||
.getTransactionFactory()
|
||||
|
@ -250,7 +249,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
// multiple transactions.
|
||||
( (Session) session ).beginTransaction();
|
||||
}
|
||||
|
||||
|
||||
session.getPersistenceContext().addUninitializedDetachedCollection(
|
||||
session.getFactory().getCollectionPersister( getRole() ),
|
||||
this
|
||||
|
@ -284,7 +283,10 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
|
||||
final SessionFactoryImplementor sf = (SessionFactoryImplementor)
|
||||
SessionFactoryRegistry.INSTANCE.getSessionFactory( sessionFactoryUuid );
|
||||
return (SessionImplementor) sf.openSession();
|
||||
final SessionImplementor session = (SessionImplementor) sf.openSession();
|
||||
session.getPersistenceContext().setDefaultReadOnly( true );
|
||||
session.setFlushMode( FlushMode.MANUAL );
|
||||
return session;
|
||||
}
|
||||
|
||||
protected Boolean readIndexExistence(final Object index) {
|
||||
|
@ -593,7 +595,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
|
||||
@Override
|
||||
public final boolean unsetSession(SessionImplementor currentSession) {
|
||||
prepareForPossibleSpecialSpecjInitialization();
|
||||
prepareForPossibleLoadingOutsideTransaction();
|
||||
if ( currentSession == this.session ) {
|
||||
this.session = null;
|
||||
return true;
|
||||
|
@ -603,11 +605,11 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
|
|||
}
|
||||
}
|
||||
|
||||
protected void prepareForPossibleSpecialSpecjInitialization() {
|
||||
protected void prepareForPossibleLoadingOutsideTransaction() {
|
||||
if ( session != null ) {
|
||||
specjLazyLoad = session.getFactory().getSettings().isInitializeLazyStateOutsideTransactionsEnabled();
|
||||
allowLoadOutsideTransaction = session.getFactory().getSettings().isInitializeLazyStateOutsideTransactionsEnabled();
|
||||
|
||||
if ( specjLazyLoad && sessionFactoryUuid == null ) {
|
||||
if ( allowLoadOutsideTransaction && sessionFactoryUuid == null ) {
|
||||
try {
|
||||
sessionFactoryUuid = (String) session.getFactory().getReference().get( "uuid" ).getContent();
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.proxy;
|
|||
import java.io.Serializable;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LazyInitializationException;
|
||||
import org.hibernate.Session;
|
||||
|
@ -59,7 +60,7 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
private Boolean readOnlyBeforeAttachedToSession;
|
||||
|
||||
private String sessionFactoryUuid;
|
||||
private boolean specjLazyLoad;
|
||||
private boolean allowLoadOutsideTransaction;
|
||||
|
||||
/**
|
||||
* For serialization from the non-pojo initializers (HHH-3309)
|
||||
|
@ -148,7 +149,7 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
|
||||
@Override
|
||||
public final void unsetSession() {
|
||||
prepareForPossibleSpecialSpecjInitialization();
|
||||
prepareForPossibleLoadingOutsideTransaction();
|
||||
session = null;
|
||||
readOnly = false;
|
||||
readOnlyBeforeAttachedToSession = null;
|
||||
|
@ -157,8 +158,8 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
@Override
|
||||
public final void initialize() throws HibernateException {
|
||||
if ( !initialized ) {
|
||||
if ( specjLazyLoad ) {
|
||||
specialSpecjInitialization();
|
||||
if ( allowLoadOutsideTransaction ) {
|
||||
permissiveInitialization();
|
||||
}
|
||||
else if ( session == null ) {
|
||||
throw new LazyInitializationException( "could not initialize proxy - no Session" );
|
||||
|
@ -180,7 +181,7 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
}
|
||||
}
|
||||
|
||||
protected void specialSpecjInitialization() {
|
||||
protected void permissiveInitialization() {
|
||||
if ( session == null ) {
|
||||
//we have a detached collection thats set to null, reattach
|
||||
if ( sessionFactoryUuid == null ) {
|
||||
|
@ -190,9 +191,9 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
SessionFactoryImplementor sf = (SessionFactoryImplementor)
|
||||
SessionFactoryRegistry.INSTANCE.getSessionFactory( sessionFactoryUuid );
|
||||
SessionImplementor session = (SessionImplementor) sf.openSession();
|
||||
|
||||
// TODO: On the next major release, add an
|
||||
// 'isJTA' or 'getTransactionFactory' method to Session.
|
||||
session.getPersistenceContext().setDefaultReadOnly( true );
|
||||
session.setFlushMode( FlushMode.MANUAL );
|
||||
|
||||
boolean isJTA = session.getTransactionCoordinator()
|
||||
.getTransactionContext().getTransactionEnvironment()
|
||||
.getTransactionFactory()
|
||||
|
@ -240,11 +241,11 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
}
|
||||
}
|
||||
|
||||
protected void prepareForPossibleSpecialSpecjInitialization() {
|
||||
protected void prepareForPossibleLoadingOutsideTransaction() {
|
||||
if ( session != null ) {
|
||||
specjLazyLoad = session.getFactory().getSettings().isInitializeLazyStateOutsideTransactionsEnabled();
|
||||
allowLoadOutsideTransaction = session.getFactory().getSettings().isInitializeLazyStateOutsideTransactionsEnabled();
|
||||
|
||||
if ( specjLazyLoad && sessionFactoryUuid == null ) {
|
||||
if ( allowLoadOutsideTransaction && sessionFactoryUuid == null ) {
|
||||
try {
|
||||
sessionFactoryUuid = (String) session.getFactory().getReference().get( "uuid" ).getContent();
|
||||
}
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. 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 Inc.
|
||||
*
|
||||
* 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.lazyload;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. 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 Inc.
|
||||
*
|
||||
* 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.lazyload;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.jta.TestingJtaBootstrap;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Oleksander Dukhno
|
||||
*/
|
||||
public class JtaLazyLoadingTest
|
||||
extends BaseCoreFunctionalTestCase {
|
||||
|
||||
private static final int CHILDREN_SIZE = 3;
|
||||
private Long parentID;
|
||||
private Long lastChildID;
|
||||
|
||||
protected void configure(Configuration cfg) {
|
||||
super.configure( cfg );
|
||||
cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" );
|
||||
|
||||
TestingJtaBootstrap.prepare( cfg.getProperties() );
|
||||
cfg.setProperty( Environment.TRANSACTION_STRATEGY, JtaTransactionFactory.class.getName() );
|
||||
}
|
||||
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Parent.class,
|
||||
Child.class
|
||||
};
|
||||
}
|
||||
|
||||
protected void prepareTest()
|
||||
throws Exception {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
|
||||
Parent p = new Parent();
|
||||
for ( int i = 0; i < CHILDREN_SIZE; i++ ) {
|
||||
final Child child = p.makeChild();
|
||||
s.persist( child );
|
||||
lastChildID = child.getId();
|
||||
}
|
||||
s.persist( p );
|
||||
parentID = p.getId();
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.clear();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-7971")
|
||||
public void testLazyCollectionLoadingAfterEndTransaction() {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
Parent loadedParent = (Parent) s.load( Parent.class, parentID );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertFalse( Hibernate.isInitialized( loadedParent.getChildren() ) );
|
||||
|
||||
int i = 0;
|
||||
for ( Child child : loadedParent.getChildren() ) {
|
||||
i++;
|
||||
assertNotNull( child );
|
||||
}
|
||||
|
||||
assertEquals( CHILDREN_SIZE, i );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
Child loadedChild = (Child) s.load( Child.class, lastChildID );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
Parent p = loadedChild.getParent();
|
||||
int j = 0;
|
||||
for ( Child child : p.getChildren() ) {
|
||||
j++;
|
||||
assertNotNull( child );
|
||||
}
|
||||
|
||||
assertEquals( CHILDREN_SIZE, j );
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +1,43 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. 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 Inc.
|
||||
*
|
||||
* 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.lazyload;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Oleksander Dukhno
|
||||
|
@ -27,8 +52,10 @@ public class LazyLoadingTest
|
|||
protected void configure(Configuration cfg) {
|
||||
super.configure( cfg );
|
||||
cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" );
|
||||
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" );
|
||||
}
|
||||
|
||||
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Parent.class,
|
||||
|
@ -41,15 +68,12 @@ public class LazyLoadingTest
|
|||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
|
||||
List<Child> children = new ArrayList<Child>();
|
||||
for ( int i = 0; i < CHILDREN_SIZE; i++ ) {
|
||||
Child c = new Child();
|
||||
s.persist( c );
|
||||
lastChildID = c.getId();
|
||||
children.add( c );
|
||||
}
|
||||
Parent p = new Parent();
|
||||
p.setChildren( children );
|
||||
for ( int i = 0; i < CHILDREN_SIZE; i++ ) {
|
||||
final Child child = p.makeChild();
|
||||
s.persist( child );
|
||||
lastChildID = child.getId();
|
||||
}
|
||||
s.persist( p );
|
||||
parentID = p.getId();
|
||||
|
||||
|
@ -63,12 +87,14 @@ public class LazyLoadingTest
|
|||
public void testLazyCollectionLoadingAfterEndTransaction() {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
Parent loadedPatent = (Parent) s.load( Parent.class, parentID );
|
||||
Parent loadedParent = (Parent) s.load( Parent.class, parentID );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertFalse( Hibernate.isInitialized( loadedParent.getChildren() ) );
|
||||
|
||||
int i = 0;
|
||||
for ( Child child : loadedPatent.getChildren() ) {
|
||||
for ( Child child : loadedParent.getChildren() ) {
|
||||
i++;
|
||||
assertNotNull( child );
|
||||
}
|
||||
|
|
|
@ -1,5 +1,30 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. 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 Inc.
|
||||
*
|
||||
* 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.lazyload;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
|
@ -7,8 +32,6 @@ import javax.persistence.GeneratedValue;
|
|||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Oleksander Dukhno
|
||||
|
@ -36,8 +59,13 @@ public class Parent {
|
|||
|
||||
public void setChildren(List<Child> children) {
|
||||
this.children = children;
|
||||
for ( Child c : children ) {
|
||||
c.setParent( this );
|
||||
}
|
||||
}
|
||||
|
||||
Child makeChild() {
|
||||
final Child c = new Child();
|
||||
c.setParent( this );
|
||||
this.children.add( c );
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue