Skip to content

Commit 4806217

Browse files
committed
cleanups after introduction of DetachedObjectException
1 parent de3d142 commit 4806217

File tree

7 files changed

+156
-129
lines changed

7 files changed

+156
-129
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.engine.internal;
6+
7+
import org.hibernate.DetachedObjectException;
8+
import org.hibernate.PersistentObjectException;
9+
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
10+
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
11+
import org.hibernate.engine.spi.SharedSessionContractImplementor;
12+
13+
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
14+
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
15+
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
16+
17+
/**
18+
* @author Gavin King
19+
* @since 7.2
20+
*/
21+
public class ProxyUtil {
22+
23+
/**
24+
* Get the entity instance underlying the given proxy, throwing
25+
* an exception if the proxy is uninitialized. If the given
26+
* object is not a proxy, simply return the argument.
27+
*/
28+
public static Object assertInitialized(Object maybeProxy) {
29+
final var lazyInitializer = extractLazyInitializer( maybeProxy );
30+
if ( lazyInitializer != null ) {
31+
if ( lazyInitializer.isUninitialized() ) {
32+
throw new PersistentObjectException( "Object was an uninitialized proxy for "
33+
+ lazyInitializer.getEntityName() );
34+
}
35+
//unwrap the object and return
36+
return lazyInitializer.getImplementation();
37+
}
38+
else {
39+
return maybeProxy;
40+
}
41+
}
42+
43+
/**
44+
* Get the entity instance underlying the given proxy, forcing
45+
* initialization if the proxy is uninitialized. If the given
46+
* object is not a proxy, simply return the argument.
47+
* @throws DetachedObjectException if the given proxy does not
48+
* belong to the given session
49+
*/
50+
public static Object forceInitialize(Object maybeProxy, SharedSessionContractImplementor session) {
51+
final var lazyInitializer = extractLazyInitializer( maybeProxy );
52+
if ( lazyInitializer != null ) {
53+
if ( lazyInitializer.getSession() != session ) {
54+
throw new DetachedObjectException( "Given proxy does not belong to this persistence context" );
55+
}
56+
//initialize + unwrap the object and return it
57+
return lazyInitializer.getImplementation();
58+
}
59+
else if ( isPersistentAttributeInterceptable( maybeProxy ) ) {
60+
final var interceptor =
61+
asPersistentAttributeInterceptable( maybeProxy )
62+
.$$_hibernate_getInterceptor();
63+
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor lazinessInterceptor ) {
64+
if ( lazinessInterceptor.getLinkedSession() != session ) {
65+
throw new DetachedObjectException( "Given proxy does not belong to this persistence context" );
66+
}
67+
lazinessInterceptor.forceInitialize( maybeProxy, null );
68+
}
69+
return maybeProxy;
70+
}
71+
else {
72+
return maybeProxy;
73+
}
74+
}
75+
76+
/**
77+
* Determine of the given proxy is uninitialized. If the given
78+
* object is not a proxy, simply return false.
79+
* @throws DetachedObjectException if the given proxy does not
80+
* belong to the given session
81+
*/
82+
public static boolean isUninitialized(Object value, SharedSessionContractImplementor session) {
83+
// could be a proxy
84+
final var lazyInitializer = extractLazyInitializer( value );
85+
if ( lazyInitializer != null ) {
86+
if ( lazyInitializer.getSession() != session ) {
87+
throw new DetachedObjectException( "Given proxy does not belong to this persistence context" );
88+
}
89+
return lazyInitializer.isUninitialized();
90+
}
91+
// or an uninitialized enhanced entity ("bytecode proxy")
92+
else if ( isPersistentAttributeInterceptable( value ) ) {
93+
final var interceptor =
94+
(BytecodeLazyAttributeInterceptor)
95+
asPersistentAttributeInterceptable( value )
96+
.$$_hibernate_getInterceptor();
97+
if ( interceptor != null && interceptor.getLinkedSession() != session ) {
98+
throw new DetachedObjectException( "Given proxy does not belong to this persistence context" );
99+
}
100+
return interceptor instanceof EnhancementAsProxyLazinessInterceptor enhancementInterceptor
101+
&& !enhancementInterceptor.isInitialized();
102+
}
103+
else {
104+
return false;
105+
}
106+
}
107+
}

hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,11 @@
2323
import java.util.function.Supplier;
2424

2525
import org.hibernate.AssertionFailure;
26-
import org.hibernate.DetachedObjectException;
2726
import org.hibernate.Hibernate;
2827
import org.hibernate.HibernateException;
2928
import org.hibernate.LockMode;
3029
import org.hibernate.MappingException;
3130
import org.hibernate.NonUniqueObjectException;
32-
import org.hibernate.PersistentObjectException;
3331
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
3432
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
3533
import org.hibernate.collection.spi.PersistentCollection;
@@ -709,33 +707,6 @@ else if ( isPersistentAttributeInterceptable( value ) ) {
709707
}
710708
}
711709

712-
@Override
713-
public boolean isUninitializedProxy(Object value) throws MappingException {
714-
// could be a proxy
715-
final var lazyInitializer = extractLazyInitializer( value );
716-
if ( lazyInitializer != null ) {
717-
if ( lazyInitializer.getSession() != session ) {
718-
throw new DetachedObjectException( "Given proxy does not belong to this persistence context" );
719-
}
720-
return lazyInitializer.isUninitialized();
721-
}
722-
// or an uninitialized enhanced entity ("bytecode proxy")
723-
else if ( isPersistentAttributeInterceptable( value ) ) {
724-
final var interceptor =
725-
(BytecodeLazyAttributeInterceptor)
726-
asPersistentAttributeInterceptable( value )
727-
.$$_hibernate_getInterceptor();
728-
if ( interceptor != null && interceptor.getLinkedSession() != session ) {
729-
throw new DetachedObjectException( "Given proxy does not belong to this persistence context" );
730-
}
731-
return interceptor instanceof EnhancementAsProxyLazinessInterceptor enhancementInterceptor
732-
&& !enhancementInterceptor.isInitialized();
733-
}
734-
else {
735-
return false;
736-
}
737-
}
738-
739710
@Override
740711
public void reassociateProxy(Object value, Object id) throws MappingException {
741712
final var lazyInitializer = extractLazyInitializer( value );
@@ -773,50 +744,6 @@ private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) {
773744
}
774745
}
775746

776-
@Override
777-
public Object unproxy(Object maybeProxy) throws HibernateException {
778-
final var lazyInitializer = extractLazyInitializer( maybeProxy );
779-
if ( lazyInitializer != null ) {
780-
if ( lazyInitializer.isUninitialized() ) {
781-
throw new PersistentObjectException( "Object was an uninitialized proxy for "
782-
+ lazyInitializer.getEntityName() );
783-
}
784-
//unwrap the object and return
785-
return lazyInitializer.getImplementation();
786-
}
787-
else {
788-
return maybeProxy;
789-
}
790-
}
791-
792-
@Override
793-
public Object unproxyLoadingIfNecessary(final Object maybeProxy) throws HibernateException {
794-
final var lazyInitializer = extractLazyInitializer( maybeProxy );
795-
if ( lazyInitializer != null ) {
796-
if ( lazyInitializer.getSession() != session ) {
797-
throw new DetachedObjectException( "Given proxy does not belong to this persistence context" );
798-
}
799-
//initialize + unwrap the object and return it
800-
return lazyInitializer.getImplementation();
801-
}
802-
else if ( isPersistentAttributeInterceptable( maybeProxy ) ) {
803-
final var interceptor =
804-
asPersistentAttributeInterceptable( maybeProxy )
805-
.$$_hibernate_getInterceptor();
806-
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor lazinessInterceptor ) {
807-
if ( lazinessInterceptor.getLinkedSession() != session ) {
808-
throw new DetachedObjectException( "Given proxy does not belong to this persistence context" );
809-
}
810-
lazinessInterceptor.forceInitialize( maybeProxy, null );
811-
}
812-
return maybeProxy;
813-
}
814-
else {
815-
return maybeProxy;
816-
}
817-
}
818-
819-
820747
@Override
821748
public Object unproxyAndReassociate(final Object maybeProxy) throws HibernateException {
822749
final var lazyInitializer = extractLazyInitializer( maybeProxy );

hibernate-core/src/main/java/org/hibernate/engine/spi/PersistenceContext.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.hibernate.Internal;
1717
import org.hibernate.LockMode;
1818
import org.hibernate.collection.spi.PersistentCollection;
19+
import org.hibernate.engine.internal.ProxyUtil;
1920
import org.hibernate.internal.util.MarkerObject;
2021
import org.hibernate.persister.collection.CollectionPersister;
2122
import org.hibernate.persister.entity.EntityPersister;
@@ -293,14 +294,12 @@ EntityEntry addReferenceEntry(
293294
* Get the entity instance underlying the given proxy, throwing
294295
* an exception if the proxy is uninitialized. If the given object
295296
* is not a proxy, simply return the argument.
297+
* @deprecated No longer used
296298
*/
297-
Object unproxy(Object maybeProxy);
298-
299-
@Incubating
300-
Object unproxyLoadingIfNecessary(final Object maybeProxy);
301-
302-
@Incubating
303-
boolean isUninitializedProxy(Object value);
299+
@Deprecated(since = "7.2", forRemoval = true)
300+
default Object unproxy(Object maybeProxy) {
301+
return ProxyUtil.assertInitialized( maybeProxy );
302+
}
304303

305304
/**
306305
* Possibly unproxy the given reference and reassociate it with the current session.

hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLockEventListener.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import org.hibernate.event.spi.LockEventListener;
1212

1313

14-
14+
import static org.hibernate.engine.internal.ProxyUtil.forceInitialize;
1515
import static org.hibernate.loader.ast.internal.LoaderHelper.upgradeLock;
1616

1717
/**
@@ -41,16 +41,15 @@ public void onLock(LockEvent event) throws HibernateException {
4141
}
4242

4343
final var source = event.getSession();
44-
final var persistenceContext = source.getPersistenceContextInternal();
45-
final Object entity = persistenceContext.unproxyLoadingIfNecessary( instance );
44+
final Object entity = forceInitialize( instance, source );
4645
//TODO: if instance was an uninitialized proxy, this is inefficient,
4746
// resulting in two SQL selects
4847

49-
final var entry = persistenceContext.getEntry( entity );
48+
final var entry = source.getPersistenceContextInternal().getEntry( entity );
5049
if ( entry == null && instance == entity ) {
5150
throw new DetachedObjectException( "Given entity is not associated with the persistence context" );
5251
}
5352

54-
upgradeLock( entity, entry, event.getLockOptions(), event.getSession() );
53+
upgradeLock( entity, entry, event.getLockOptions(), source );
5554
}
5655
}

hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
4141
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
4242
import static org.hibernate.engine.internal.ManagedTypeHelper.isSelfDirtinessTracker;
43+
import static org.hibernate.engine.internal.ProxyUtil.assertInitialized;
4344
import static org.hibernate.event.internal.EntityState.getEntityState;
4445
import static org.hibernate.event.internal.EventListenerLogging.EVENT_LISTENER_LOGGER;
4546
import static org.hibernate.event.internal.EventUtil.getLoggableName;
@@ -515,7 +516,7 @@ private static Object unproxyManagedForDetachedMerging(
515516
EntityPersister persister,
516517
EventSource source) {
517518
if ( isHibernateProxy( managed ) ) {
518-
return source.getPersistenceContextInternal().unproxy( managed );
519+
return assertInitialized( managed );
519520
}
520521

521522
if ( isPersistentAttributeInterceptable( incoming )

hibernate-core/src/main/java/org/hibernate/event/internal/DefaultPersistEventListener.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
1919
import org.hibernate.persister.entity.EntityPersister;
2020

21+
import static org.hibernate.engine.internal.ProxyUtil.assertInitialized;
2122
import static org.hibernate.event.internal.EntityState.getEntityState;
2223
import static org.hibernate.event.internal.EventListenerLogging.EVENT_LISTENER_LOGGER;
2324
import static org.hibernate.event.internal.EventUtil.getLoggableName;
@@ -118,14 +119,13 @@ protected void entityIsPersistent(PersistEvent event, PersistContext createCache
118119
final var source = event.getSession();
119120
final String entityName = event.getEntityName();
120121
//TODO: check that entry.getIdentifier().equals(requestedId)
121-
final Object entity = source.getPersistenceContextInternal().unproxy( event.getObject() );
122+
final Object entity = assertInitialized( event.getObject() );
123+
final var persister = source.getEntityPersister( entityName, entity );
122124
if ( EVENT_LISTENER_LOGGER.isTraceEnabled() ) {
123-
final var persister = source.getEntityPersister( entityName, entity );
124125
EVENT_LISTENER_LOGGER.ignoringPersistentInstance(
125126
infoString( entityName, persister.getIdentifier( entity ) ) );
126127
}
127128
if ( createCache.add( entity ) ) {
128-
final var persister = source.getEntityPersister( entityName, entity );
129129
justCascade( createCache, source, entity, persister );
130130
}
131131
}
@@ -138,21 +138,20 @@ private void justCascade(PersistContext createCache, EventSource source, Object
138138

139139
protected void entityIsTransient(PersistEvent event, PersistContext createCache) {
140140
EVENT_LISTENER_LOGGER.persistingTransientInstance();
141-
final var source = event.getSession();
142-
final Object entity = source.getPersistenceContextInternal().unproxy( event.getObject() );
141+
final Object entity = assertInitialized( event.getObject() );
143142
if ( createCache.add( entity ) ) {
143+
final var source = event.getSession();
144144
saveWithGeneratedId( entity, event.getEntityName(), createCache, source, false );
145145
}
146146
}
147147

148148
private void entityIsDeleted(PersistEvent event, PersistContext createCache) {
149149
final var source = event.getSession();
150-
final Object entity = source.getPersistenceContextInternal().unproxy( event.getObject() );
150+
final Object entity = assertInitialized( event.getObject() );
151151
final var persister = source.getEntityPersister( event.getEntityName(), entity );
152152
if ( EVENT_LISTENER_LOGGER.isTraceEnabled() ) {
153-
final Object id = persister.getIdentifier( entity, source );
154153
EVENT_LISTENER_LOGGER.unschedulingEntityDeletion(
155-
infoString( persister, id, source.getFactory() ) );
154+
infoString( persister, persister.getIdentifier( entity, source ), source.getFactory() ) );
156155
}
157156
if ( createCache.add( entity ) ) {
158157
justCascade( createCache, source, entity, persister );

0 commit comments

Comments
 (0)