20
20
import org .hibernate .cache .spi .entry .ReferenceCacheEntryImpl ;
21
21
import org .hibernate .cache .spi .entry .StandardCacheEntryImpl ;
22
22
import org .hibernate .engine .internal .CacheHelper ;
23
+ import org .hibernate .engine .internal .StatefulPersistenceContext ;
23
24
import org .hibernate .engine .internal .TwoPhaseLoad ;
24
25
import org .hibernate .engine .internal .Versioning ;
25
26
import org .hibernate .engine .spi .EntityEntry ;
26
27
import org .hibernate .engine .spi .EntityKey ;
28
+ import org .hibernate .engine .spi .ManagedEntity ;
27
29
import org .hibernate .engine .spi .PersistenceContext ;
28
30
import org .hibernate .engine .spi .SessionFactoryImplementor ;
29
31
import org .hibernate .engine .spi .SessionImplementor ;
30
32
import org .hibernate .engine .spi .Status ;
33
+ import org .hibernate .event .service .spi .EventListenerGroup ;
31
34
import org .hibernate .event .service .spi .EventListenerRegistry ;
32
35
import org .hibernate .event .spi .EventSource ;
33
36
import org .hibernate .event .spi .EventType ;
@@ -603,19 +606,101 @@ protected Object loadFromSecondLevelCache(
603
606
}
604
607
605
608
CacheEntry entry = (CacheEntry ) persister .getCacheEntryStructure ().destructure ( ce , factory );
606
- Object entity = convertCacheEntryToEntity ( entry , event .getEntityId (), persister , event , entityKey );
607
-
609
+ final Object entity ;
610
+ if (entry .isReferenceEntry ()) {
611
+ if ( event .getInstanceToLoad () != null ) {
612
+ throw new HibernateException (
613
+ String .format ( "Attempt to load entity [%s] from cache using provided object instance, but cache " +
614
+ "is storing references: " + event .getEntityId ()));
615
+ }
616
+ else {
617
+ entity = convertCacheReferenceEntryToEntity ( (ReferenceCacheEntryImpl ) entry ,
618
+ event .getEntityId (), persister , event .getSession (), entityKey );
619
+ }
620
+ }
621
+ else {
622
+ entity = convertCacheEntryToEntity ( entry , event .getEntityId (), persister , event , entityKey );
623
+ }
624
+
608
625
if ( !persister .isInstance ( entity ) ) {
609
626
throw new WrongClassException (
610
627
"loaded object was of wrong class " + entity .getClass (),
611
628
event .getEntityId (),
612
629
persister .getEntityName ()
613
630
);
614
631
}
615
-
632
+
616
633
return entity ;
617
634
}
618
635
636
+ private Object convertCacheReferenceEntryToEntity (
637
+ ReferenceCacheEntryImpl referenceCacheEntry ,
638
+ Serializable entityId ,
639
+ EntityPersister persister ,
640
+ EventSource session ,
641
+ EntityKey entityKey ) {
642
+ final Object entity = referenceCacheEntry .getReference ();
643
+
644
+ if ( entity == null ) {
645
+ throw new IllegalStateException (
646
+ "Reference cache entry contained null : " + entityId );
647
+ }
648
+ else {
649
+ makeEntityCircularReferenceSafe (referenceCacheEntry , entityId , session , entity , entityKey );
650
+ //PostLoad is needed for EJB3
651
+ EventListenerGroup <PostLoadEventListener > evenListenerGroup = getEvenListenerGroup (session );
652
+
653
+ if (!evenListenerGroup .isEmpty ()) {
654
+ postLoad (session , evenListenerGroup .listeners (), entity , entityId , persister );
655
+ }
656
+ return entity ;
657
+ }
658
+ }
659
+
660
+ private void postLoad (EventSource session , Iterable <PostLoadEventListener > listeners ,
661
+ Object entity , Serializable entityId , EntityPersister persister ) {
662
+ PostLoadEvent postLoadEvent = new PostLoadEvent (session )
663
+ .setEntity (entity )
664
+ .setId (entityId )
665
+ .setPersister (persister );
666
+
667
+ for (PostLoadEventListener listener : listeners ) {
668
+ listener .onPostLoad (postLoadEvent );
669
+ }
670
+ }
671
+
672
+ private void makeEntityCircularReferenceSafe (ReferenceCacheEntryImpl referenceCacheEntry ,
673
+ Serializable entityId ,
674
+ EventSource session ,
675
+ Object entity ,
676
+ EntityKey entityKey ) {
677
+
678
+ final EntityPersister subclassPersister = referenceCacheEntry .getSubclassPersister ();
679
+ // make it circular-reference safe
680
+ final StatefulPersistenceContext statefulPersistenceContext = (StatefulPersistenceContext ) session .getPersistenceContext ();
681
+
682
+ if ( (entity instanceof ManagedEntity ) ) {
683
+ statefulPersistenceContext .addReferenceEntry (
684
+ entity ,
685
+ Status .READ_ONLY
686
+ );
687
+ }
688
+ else {
689
+ TwoPhaseLoad .addUninitializedCachedEntity (
690
+ entityKey ,
691
+ entity ,
692
+ subclassPersister ,
693
+ LockMode .NONE ,
694
+ referenceCacheEntry .areLazyPropertiesUnfetched (),
695
+ referenceCacheEntry .getVersion (),
696
+ session
697
+ );
698
+ }
699
+
700
+ subclassPersister .afterInitialize ( entity , referenceCacheEntry .areLazyPropertiesUnfetched (), session );
701
+ statefulPersistenceContext .initializeNonLazyCollections ();
702
+ }
703
+
619
704
private Object convertCacheEntryToEntity (
620
705
CacheEntry entry ,
621
706
Serializable entityId ,
@@ -636,38 +721,12 @@ private Object convertCacheEntryToEntity(
636
721
}
637
722
638
723
final Object entity ;
639
- if ( entry .isReferenceEntry () ) {
640
- final Object optionalObject = event .getInstanceToLoad ();
641
- if ( optionalObject != null ) {
642
- throw new HibernateException (
643
- String .format (
644
- "Attempt to load entity [%s] from cache using provided object instance, but cache " +
645
- "is storing references" ,
646
- MessageHelper .infoString ( persister , entityId , factory )
647
- )
648
- );
649
- }
650
724
651
- ReferenceCacheEntryImpl referenceCacheEntry = (ReferenceCacheEntryImpl ) entry ;
652
- entity = referenceCacheEntry .getReference ();
653
- if ( entity == null ) {
654
- throw new IllegalStateException (
655
- "Reference cache entry contained null : " + MessageHelper .infoString (
656
- persister ,
657
- entityId ,
658
- factory
659
- )
660
- );
661
- }
662
- subclassPersister = referenceCacheEntry .getSubclassPersister ();
663
- }
664
- else {
665
- subclassPersister = factory .getEntityPersister ( entry .getSubclass () );
666
- final Object optionalObject = event .getInstanceToLoad ();
667
- entity = optionalObject == null
668
- ? session .instantiate ( subclassPersister , entityId )
669
- : optionalObject ;
670
- }
725
+ subclassPersister = factory .getEntityPersister ( entry .getSubclass () );
726
+ final Object optionalObject = event .getInstanceToLoad ();
727
+ entity = optionalObject == null
728
+ ? session .instantiate ( subclassPersister , entityId )
729
+ : optionalObject ;
671
730
672
731
// make it circular-reference safe
673
732
TwoPhaseLoad .addUninitializedCachedEntity (
@@ -684,38 +743,32 @@ private Object convertCacheEntryToEntity(
684
743
final Object [] values ;
685
744
final Object version ;
686
745
final boolean isReadOnly ;
687
- if ( entry .isReferenceEntry () ) {
688
- values = null ;
689
- version = null ;
690
- isReadOnly = true ;
691
- }
692
- else {
693
- final Type [] types = subclassPersister .getPropertyTypes ();
694
- // initializes the entity by (desired) side-effect
695
- values = ( (StandardCacheEntryImpl ) entry ).assemble (
696
- entity , entityId , subclassPersister , session .getInterceptor (), session
746
+
747
+ final Type [] types = subclassPersister .getPropertyTypes ();
748
+ // initializes the entity by (desired) side-effect
749
+ values = ( (StandardCacheEntryImpl ) entry ).assemble (
750
+ entity , entityId , subclassPersister , session .getInterceptor (), session
751
+ );
752
+ if ( ( (StandardCacheEntryImpl ) entry ).isDeepCopyNeeded () ) {
753
+ TypeHelper .deepCopy (
754
+ values ,
755
+ types ,
756
+ subclassPersister .getPropertyUpdateability (),
757
+ values ,
758
+ session
697
759
);
698
- if ( ( (StandardCacheEntryImpl ) entry ).isDeepCopyNeeded () ) {
699
- TypeHelper .deepCopy (
700
- values ,
701
- types ,
702
- subclassPersister .getPropertyUpdateability (),
703
- values ,
704
- session
705
- );
706
- }
707
- version = Versioning .getVersion ( values , subclassPersister );
708
- LOG .tracef ( "Cached Version : %s" , version );
760
+ }
761
+ version = Versioning .getVersion ( values , subclassPersister );
762
+ LOG .tracef ( "Cached Version : %s" , version );
709
763
710
- final Object proxy = persistenceContext .getProxy ( entityKey );
711
- if ( proxy != null ) {
712
- // there is already a proxy for this impl
713
- // only set the status to read-only if the proxy is read-only
714
- isReadOnly = ( (HibernateProxy ) proxy ).getHibernateLazyInitializer ().isReadOnly ();
715
- }
716
- else {
717
- isReadOnly = session .isDefaultReadOnly ();
718
- }
764
+ final Object proxy = persistenceContext .getProxy ( entityKey );
765
+ if ( proxy != null ) {
766
+ // there is already a proxy for this impl
767
+ // only set the status to read-only if the proxy is read-only
768
+ isReadOnly = ( (HibernateProxy ) proxy ).getHibernateLazyInitializer ().isReadOnly ();
769
+ }
770
+ else {
771
+ isReadOnly = session .isDefaultReadOnly ();
719
772
}
720
773
721
774
persistenceContext .addEntry (
@@ -852,4 +905,14 @@ private Iterable<PostLoadEventListener> postLoadEventListeners(EventSource sessi
852
905
.getEventListenerGroup ( EventType .POST_LOAD )
853
906
.listeners ();
854
907
}
908
+
909
+ private EventListenerGroup <PostLoadEventListener > getEvenListenerGroup (EventSource session ) {
910
+ return session
911
+ .getFactory ()
912
+ .getServiceRegistry ()
913
+ .getService ( EventListenerRegistry .class )
914
+ .getEventListenerGroup ( EventType .POST_LOAD );
915
+
916
+ }
917
+
855
918
}
0 commit comments