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 (
@@ -683,38 +742,32 @@ private Object convertCacheEntryToEntity(
683
742
final Object [] values ;
684
743
final Object version ;
685
744
final boolean isReadOnly ;
686
- if ( entry .isReferenceEntry () ) {
687
- values = null ;
688
- version = null ;
689
- isReadOnly = true ;
690
- }
691
- else {
692
- final Type [] types = subclassPersister .getPropertyTypes ();
693
- // initializes the entity by (desired) side-effect
694
- values = ( (StandardCacheEntryImpl ) entry ).assemble (
695
- entity , entityId , subclassPersister , session .getInterceptor (), session
745
+
746
+ final Type [] types = subclassPersister .getPropertyTypes ();
747
+ // initializes the entity by (desired) side-effect
748
+ values = ( (StandardCacheEntryImpl ) entry ).assemble (
749
+ entity , entityId , subclassPersister , session .getInterceptor (), session
750
+ );
751
+ if ( ( (StandardCacheEntryImpl ) entry ).isDeepCopyNeeded () ) {
752
+ TypeHelper .deepCopy (
753
+ values ,
754
+ types ,
755
+ subclassPersister .getPropertyUpdateability (),
756
+ values ,
757
+ session
696
758
);
697
- if ( ( (StandardCacheEntryImpl ) entry ).isDeepCopyNeeded () ) {
698
- TypeHelper .deepCopy (
699
- values ,
700
- types ,
701
- subclassPersister .getPropertyUpdateability (),
702
- values ,
703
- session
704
- );
705
- }
706
- version = Versioning .getVersion ( values , subclassPersister );
707
- LOG .tracef ( "Cached Version : %s" , version );
759
+ }
760
+ version = Versioning .getVersion ( values , subclassPersister );
761
+ LOG .tracef ( "Cached Version : %s" , version );
708
762
709
- final Object proxy = persistenceContext .getProxy ( entityKey );
710
- if ( proxy != null ) {
711
- // there is already a proxy for this impl
712
- // only set the status to read-only if the proxy is read-only
713
- isReadOnly = ( (HibernateProxy ) proxy ).getHibernateLazyInitializer ().isReadOnly ();
714
- }
715
- else {
716
- isReadOnly = session .isDefaultReadOnly ();
717
- }
763
+ final Object proxy = persistenceContext .getProxy ( entityKey );
764
+ if ( proxy != null ) {
765
+ // there is already a proxy for this impl
766
+ // only set the status to read-only if the proxy is read-only
767
+ isReadOnly = ( (HibernateProxy ) proxy ).getHibernateLazyInitializer ().isReadOnly ();
768
+ }
769
+ else {
770
+ isReadOnly = session .isDefaultReadOnly ();
718
771
}
719
772
720
773
persistenceContext .addEntry (
@@ -848,4 +901,14 @@ private Iterable<PostLoadEventListener> postLoadEventListeners(EventSource sessi
848
901
.getEventListenerGroup ( EventType .POST_LOAD )
849
902
.listeners ();
850
903
}
904
+
905
+ private EventListenerGroup <PostLoadEventListener > getEvenListenerGroup (EventSource session ) {
906
+ return session
907
+ .getFactory ()
908
+ .getServiceRegistry ()
909
+ .getService ( EventListenerRegistry .class )
910
+ .getEventListenerGroup ( EventType .POST_LOAD );
911
+
912
+ }
913
+
851
914
}
0 commit comments