|
32 | 32 | import org.hibernate.metamodel.spi.MappingMetamodelImplementor; |
33 | 33 | import org.hibernate.persister.collection.CollectionPersister; |
34 | 34 | import org.hibernate.persister.entity.EntityPersister; |
| 35 | +import org.hibernate.proxy.HibernateProxy; |
| 36 | +import org.hibernate.proxy.LazyInitializer; |
35 | 37 | import org.hibernate.type.CollectionType; |
36 | 38 | import org.hibernate.type.CompositeType; |
37 | 39 | import org.hibernate.type.Type; |
@@ -61,7 +63,22 @@ public void onRefresh(RefreshEvent event, RefreshContext refreshedAlready) { |
61 | 63 | final PersistenceContext persistenceContext = source.getPersistenceContextInternal(); |
62 | 64 | final Object object = event.getObject(); |
63 | 65 | if ( persistenceContext.reassociateIfUninitializedProxy( object ) ) { |
64 | | - if ( isTransient( event, source, object ) ) { |
| 66 | + final boolean isTransient = isTransient( event, source, object ); |
| 67 | + |
| 68 | + final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object ); |
| 69 | + final EntityPersister persister = source.getEntityPersister( lazyInitializer.getEntityName(), object ); |
| 70 | + refresh( |
| 71 | + event, |
| 72 | + null, |
| 73 | + source, |
| 74 | + persister, |
| 75 | + lazyInitializer, |
| 76 | + null, |
| 77 | + persister.getIdentifier( object, event.getSession() ), |
| 78 | + persistenceContext |
| 79 | + ); |
| 80 | + |
| 81 | + if ( isTransient ) { |
65 | 82 | source.setReadOnly( object, source.isDefaultReadOnly() ); |
66 | 83 | } |
67 | 84 | } |
@@ -147,9 +164,22 @@ private static void refresh(RefreshEvent event, RefreshContext refreshedAlready, |
147 | 164 | evictEntity( object, persister, id, source ); |
148 | 165 | evictCachedCollections( persister, id, source ); |
149 | 166 |
|
| 167 | + refresh( event, object, source, persister, null, entry, id, persistenceContext ); |
| 168 | + } |
| 169 | + |
| 170 | + private static void refresh( |
| 171 | + RefreshEvent event, |
| 172 | + Object object, |
| 173 | + EventSource source, |
| 174 | + EntityPersister persister, |
| 175 | + LazyInitializer lazyInitializer, |
| 176 | + EntityEntry entry, |
| 177 | + Object id, |
| 178 | + PersistenceContext persistenceContext) { |
| 179 | + |
150 | 180 | final Object result = source.getLoadQueryInfluencers().fromInternalFetchProfile( |
151 | 181 | CascadingFetchProfile.REFRESH, |
152 | | - () -> doRefresh( event, source, object, entry, persister, id, persistenceContext ) |
| 182 | + () -> doRefresh( event, source, object, entry, persister, lazyInitializer, id, persistenceContext ) |
153 | 183 | ); |
154 | 184 | UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() ); |
155 | 185 | } |
@@ -182,6 +212,7 @@ private static Object doRefresh( |
182 | 212 | Object object, |
183 | 213 | EntityEntry entry, |
184 | 214 | EntityPersister persister, |
| 215 | + LazyInitializer lazyInitializer, |
185 | 216 | Object id, |
186 | 217 | PersistenceContext persistenceContext) { |
187 | 218 | // Handle the requested lock-mode (if one) in relation to the entry's (if one) current lock-mode |
@@ -231,19 +262,32 @@ private static Object doRefresh( |
231 | 262 | persistenceContext.getEntry( result ).setLockMode( postRefreshLockMode ); |
232 | 263 | } |
233 | 264 |
|
234 | | - // Keep the same read-only/modifiable setting for the entity that it had before refreshing; |
235 | | - // If it was transient, then set it to the default for the source. |
236 | | - if ( !persister.isMutable() ) { |
237 | | - // this is probably redundant; it should already be read-only |
238 | | - source.setReadOnly( result, true ); |
239 | | - } |
240 | | - else { |
241 | | - source.setReadOnly( result, entry == null ? source.isDefaultReadOnly() : entry.isReadOnly() ); |
242 | | - } |
| 265 | + source.setReadOnly( result, isReadOnly( entry, persister, lazyInitializer, source ) ); |
243 | 266 | } |
244 | 267 | return result; |
245 | 268 | } |
246 | 269 |
|
| 270 | + private static boolean isReadOnly( |
| 271 | + EntityEntry entry, |
| 272 | + EntityPersister persister, |
| 273 | + LazyInitializer lazyInitializer, |
| 274 | + EventSource source) { |
| 275 | + // Keep the same read-only/modifiable setting for the entity that it had before refreshing; |
| 276 | + // If it was transient, then set it to the default for the source. |
| 277 | + if ( !persister.isMutable() ) { |
| 278 | + return true; |
| 279 | + } |
| 280 | + else if ( entry != null ) { |
| 281 | + return entry.isReadOnly(); |
| 282 | + } |
| 283 | + else if ( lazyInitializer != null ) { |
| 284 | + return lazyInitializer.isReadOnly(); |
| 285 | + } |
| 286 | + else { |
| 287 | + return source.isDefaultReadOnly(); |
| 288 | + } |
| 289 | + } |
| 290 | + |
247 | 291 | private static void evictCachedCollections(EntityPersister persister, Object id, EventSource source) { |
248 | 292 | evictCachedCollections( persister.getPropertyTypes(), id, source ); |
249 | 293 | } |
|
0 commit comments