From dd14feac5ac7b2d348749bd6ed5996fc47b42dcc Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 18 Oct 2016 06:48:36 +0300 Subject: [PATCH] HHH-11179 - NullPointerException on lazy load of non-existed entity outside transaction --- .../proxy/AbstractLazyInitializer.java | 23 ++++---- .../lazyload/LazyLoadingNotFoundTest.java | 53 +++++++++++++++++++ 2 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/lazyload/LazyLoadingNotFoundTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java b/hibernate-core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java index 8c465ac998..3afdd902b9 100755 --- a/hibernate-core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java @@ -11,7 +11,6 @@ import java.io.Serializable; import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.LazyInitializationException; -import org.hibernate.Session; import org.hibernate.SessionException; import org.hibernate.TransientObjectException; import org.hibernate.engine.spi.EntityKey; @@ -155,11 +154,11 @@ public abstract class AbstractLazyInitializer implements LazyInitializer { else { target = session.immediateLoad( entityName, id ); initialized = true; - checkTargetState(); + checkTargetState(session); } } else { - checkTargetState(); + checkTargetState(session); } } @@ -184,36 +183,36 @@ public abstract class AbstractLazyInitializer implements LazyInitializer { // be created even if a current session and transaction are // open (ex: session.clear() was used). We must prevent // multiple transactions. - ( ( Session) session ).beginTransaction(); + session.beginTransaction(); } try { target = session.immediateLoad( entityName, id ); + initialized = true; + checkTargetState(session); } finally { // make sure the just opened temp session gets closed! try { if ( !isJTA ) { - ( ( Session) session ).getTransaction().commit(); + session.getTransaction().commit(); } - ( (Session) session ).close(); + session.close(); } catch (Exception e) { log.warn( "Unable to close temporary session used to load lazy proxy associated to no session" ); } } - initialized = true; - checkTargetState(); } catch (Exception e) { - e.printStackTrace(); + log.error( "Initialization failure", e ); throw new LazyInitializationException( e.getMessage() ); } } else if ( session.isOpen() && session.isConnected() ) { target = session.immediateLoad( entityName, id ); initialized = true; - checkTargetState(); + checkTargetState(session); } else { throw new LazyInitializationException( "could not initialize proxy - Session was closed or disced" ); @@ -230,10 +229,10 @@ public abstract class AbstractLazyInitializer implements LazyInitializer { } } - private void checkTargetState() { + private void checkTargetState(SharedSessionContractImplementor session) { if ( !unwrap ) { if ( target == null ) { - getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id ); + session.getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id ); } } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/lazyload/LazyLoadingNotFoundTest.java b/hibernate-core/src/test/java/org/hibernate/test/lazyload/LazyLoadingNotFoundTest.java new file mode 100644 index 0000000000..59825c0524 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/lazyload/LazyLoadingNotFoundTest.java @@ -0,0 +1,53 @@ +/* + * 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.lazyload; + +import org.hibernate.LazyInitializationException; +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 static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +/** + * @author Nikolay Golubev + */ +public class LazyLoadingNotFoundTest extends BaseCoreFunctionalTestCase { + + protected void configure(Configuration cfg) { + super.configure(cfg); + cfg.setProperty(Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true"); + } + + protected Class[] getAnnotatedClasses() { + return new Class[]{ + Parent.class, + Child.class + }; + } + + @Test + @TestForIssue(jiraKey = "HHH-11179") + public void testNonExistentLazyInitOutsideTransaction() { + Session s = openSession(); + s.beginTransaction(); + Child loadedChild = s.load(Child.class, -1L); + s.getTransaction().commit(); + s.close(); + + try { + loadedChild.getParent(); + fail("lazy init did not fail on non-existent proxy"); + } catch (LazyInitializationException e) { + assertNotNull(e.getMessage()); + } + } +}