KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > engine > TwoPhaseLoad


1 //$Id: TwoPhaseLoad.java,v 1.36 2005/07/12 20:12:53 oneovthafew Exp $
2
package org.hibernate.engine;
3
4 import java.io.Serializable JavaDoc;
5
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
8 import org.hibernate.AssertionFailure;
9 import org.hibernate.CacheMode;
10 import org.hibernate.HibernateException;
11 import org.hibernate.LockMode;
12 import org.hibernate.cache.CacheKey;
13 import org.hibernate.cache.entry.CacheEntry;
14 import org.hibernate.event.PostLoadEvent;
15 import org.hibernate.event.PreLoadEvent;
16 import org.hibernate.intercept.LazyPropertyInitializer;
17 import org.hibernate.persister.entity.EntityPersister;
18 import org.hibernate.pretty.MessageHelper;
19 import org.hibernate.property.BackrefPropertyAccessor;
20 import org.hibernate.type.Type;
21 import org.hibernate.type.TypeFactory;
22
23 /**
24  * Functionality relating to Hibernate's two-phase loading process,
25  * that may be reused by persisters that do not use the Loader
26  * framework
27  *
28  * @author Gavin King
29  */

30 public final class TwoPhaseLoad {
31
32     private static final Log log = LogFactory.getLog(TwoPhaseLoad.class);
33     
34     private TwoPhaseLoad() {}
35
36     /**
37      * Register the "hydrated" state of an entity instance, after the first step of 2-phase loading.
38      *
39      * Add the "hydrated state" (an array) of an uninitialized entity to the session. We don't try
40      * to resolve any associations yet, because there might be other entities waiting to be
41      * read from the JDBC result set we are currently processing
42      */

43     public static void postHydrate(
44         final EntityPersister persister,
45         final Serializable JavaDoc id,
46         final Object JavaDoc[] values,
47         final Object JavaDoc rowId,
48         final Object JavaDoc object,
49         final LockMode lockMode,
50         final boolean lazyPropertiesAreUnfetched,
51         final SessionImplementor session)
52     throws HibernateException {
53         
54         Object JavaDoc version = Versioning.getVersion(values, persister);
55         session.getPersistenceContext().addEntry(
56                 object,
57                 Status.LOADING,
58                 values,
59                 rowId,
60                 id,
61                 version,
62                 lockMode,
63                 true,
64                 persister,
65                 false,
66                 lazyPropertiesAreUnfetched
67             );
68     
69         if ( log.isTraceEnabled() && version!=null ) {
70             log.trace( "Version: " + version );
71         }
72     
73     }
74
75     /**
76      * Perform the second step of 2-phase load. Fully initialize the entity
77      * instance.
78      *
79      * After processing a JDBC result set, we "resolve" all the associations
80      * between the entities which were instantiated and had their state
81      * "hydrated" into an array
82      */

83     public static void initializeEntity(
84             final Object JavaDoc entity,
85             final boolean readOnly,
86             final SessionImplementor session,
87             final PreLoadEvent preLoadEvent,
88             final PostLoadEvent postLoadEvent) throws HibernateException {
89         
90         //TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)
91

92         final PersistenceContext persistenceContext = session.getPersistenceContext();
93         EntityEntry entityEntry = persistenceContext.getEntry(entity);
94         if ( entityEntry == null ) {
95             throw new AssertionFailure( "possible non-threadsafe access to the session" );
96         }
97         EntityPersister persister = entityEntry.getPersister();
98         Serializable JavaDoc id = entityEntry.getId();
99         Object JavaDoc[] hydratedState = entityEntry.getLoadedState();
100     
101         if ( log.isDebugEnabled() )
102             log.debug(
103                     "resolving associations for " +
104                     MessageHelper.infoString(persister, id, session.getFactory())
105             );
106     
107         Type[] types = persister.getPropertyTypes();
108         for ( int i = 0; i < hydratedState.length; i++ ) {
109             final Object JavaDoc value = hydratedState[i];
110             if ( value!=LazyPropertyInitializer.UNFETCHED_PROPERTY && value!=BackrefPropertyAccessor.UNKNOWN ) {
111                 hydratedState[i] = types[i].resolve( value, session, entity );
112             }
113         }
114     
115         //Must occur after resolving identifiers!
116
if ( session.isEventSource() ) {
117             preLoadEvent.setEntity(entity).setState(hydratedState).setId(id).setPersister(persister);
118             session.getListeners().getPreLoadEventListener().onPreLoad(preLoadEvent);
119         }
120     
121         persister.setPropertyValues( entity, hydratedState, session.getEntityMode() );
122     
123         final SessionFactoryImplementor factory = session.getFactory();
124         if ( persister.hasCache() && session.getCacheMode().isPutEnabled() ) {
125             
126             if ( log.isDebugEnabled() )
127                 log.debug(
128                         "adding entity to second-level cache: " +
129                         MessageHelper.infoString( persister, id, session.getFactory() )
130                     );
131
132             CacheEntry entry = new CacheEntry(hydratedState, persister, true, session, entity);
133             CacheKey cacheKey = new CacheKey(
134                     id,
135                     persister.getIdentifierType(),
136                     persister.getRootEntityName(),
137                     session.getEntityMode(),
138                     session.getFactory()
139                 );
140             boolean put = persister.getCache().put(
141                     cacheKey,
142                     persister.getCacheEntryStructure().structure(entry),
143                     session.getTimestamp(),
144                     Versioning.getVersion(hydratedState, persister),
145                     persister.isVersioned() ?
146                             persister.getVersionType().getComparator() :
147                             null,
148                     factory.getSettings().isMinimalPutsEnabled() &&
149                             session.getCacheMode()!=CacheMode.REFRESH
150                 ); //we could use persister.hasLazyProperties() instead of true
151

152             if ( put && factory.getStatistics().isStatisticsEnabled() ) {
153                 factory.getStatisticsImplementor().secondLevelCachePut( persister.getCache().getRegionName() );
154             }
155         }
156     
157         if ( readOnly || !persister.isMutable() ) {
158             //no need to take a snapshot - this is a
159
//performance optimization, but not really
160
//important, except for entities with huge
161
//mutable property values
162
persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
163         }
164         else {
165             //take a snapshot
166
TypeFactory.deepCopy(
167                     hydratedState,
168                     persister.getPropertyTypes(),
169                     persister.getPropertyUpdateability(),
170                     hydratedState, //after setting values to object, entityMode
171
session
172                 );
173             persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
174         }
175         
176         persister.afterInitialize(
177                 entity,
178                 entityEntry.isLoadedWithLazyPropertiesUnfetched(),
179                 session
180             );
181         
182         if ( session.isEventSource() ) {
183             postLoadEvent.setEntity(entity).setId(id).setPersister(persister);
184             session.getListeners().getPostLoadEventListener().onPostLoad(postLoadEvent);
185         }
186         
187         if ( log.isDebugEnabled() )
188             log.debug(
189                     "done materializing entity " +
190                     MessageHelper.infoString( persister, id, session.getFactory() )
191                 );
192         
193         if ( factory.getStatistics().isStatisticsEnabled() ) {
194             factory.getStatisticsImplementor().loadEntity( persister.getEntityName() );
195         }
196     
197     }
198
199     /**
200      * Add an uninitialized instance of an entity class, as a placeholder to ensure object
201      * identity. Must be called before <tt>postHydrate()</tt>.
202      *
203      * Create a "temporary" entry for a newly instantiated entity. The entity is uninitialized,
204      * but we need the mapping from id to instance in order to guarantee uniqueness.
205      */

206     public static void addUninitializedEntity(
207             final EntityKey key,
208             final Object JavaDoc object,
209             final EntityPersister persister,
210             final LockMode lockMode,
211             final boolean lazyPropertiesAreUnfetched,
212             final SessionImplementor session
213     ) {
214         session.getPersistenceContext().addEntity(
215                 object,
216                 Status.LOADING,
217                 null,
218                 key,
219                 null,
220                 lockMode,
221                 true,
222                 persister,
223                 false,
224                 lazyPropertiesAreUnfetched
225             );
226     }
227 }
228
Popular Tags