001: //$Id: EntityPersister.java 11061 2007-01-19 12:55:07Z steve.ebersole@jboss.com $
002: package org.hibernate.persister.entity;
003:
004: import java.io.Serializable;
005: import java.util.Map;
006:
007: import org.hibernate.HibernateException;
008: import org.hibernate.LockMode;
009: import org.hibernate.MappingException;
010: import org.hibernate.EntityMode;
011: import org.hibernate.tuple.entity.EntityMetamodel;
012: import org.hibernate.cache.CacheConcurrencyStrategy;
013: import org.hibernate.cache.OptimisticCacheSource;
014: import org.hibernate.cache.entry.CacheEntryStructure;
015: import org.hibernate.engine.CascadeStyle;
016: import org.hibernate.engine.SessionFactoryImplementor;
017: import org.hibernate.engine.SessionImplementor;
018: import org.hibernate.engine.ValueInclusion;
019: import org.hibernate.id.IdentifierGenerator;
020: import org.hibernate.metadata.ClassMetadata;
021: import org.hibernate.type.Type;
022: import org.hibernate.type.VersionType;
023:
024: /**
025: * Implementors define mapping and persistence logic for a particular
026: * strategy of entity mapping. An instance of entity persisters corresponds
027: * to a given mapped entity.
028: * <p/>
029: * Implementors must be threadsafe (preferrably immutable) and must provide a constructor
030: * matching the signature of: {@link org.hibernate.mapping.PersistentClass}, {@link org.hibernate.engine.SessionFactoryImplementor}
031: *
032: * @author Gavin King
033: */
034: public interface EntityPersister extends OptimisticCacheSource {
035:
036: /**
037: * The property name of the "special" identifier property in HQL
038: */
039: public static final String ENTITY_ID = "id";
040:
041: /**
042: * Finish the initialization of this object.
043: * <p/>
044: * Called only once per {@link org.hibernate.SessionFactory} lifecycle,
045: * after all entity persisters have been instantiated.
046: *
047: * @throws org.hibernate.MappingException Indicates an issue in the metdata.
048: */
049: public void postInstantiate() throws MappingException;
050:
051: /**
052: * Return the SessionFactory to which this persister "belongs".
053: *
054: * @return The owning SessionFactory.
055: */
056: public SessionFactoryImplementor getFactory();
057:
058: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
059: // stuff that is persister-centric and/or EntityInfo-centric ~~~~~~~~~~~~~~
060: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
061:
062: /**
063: * Returns an object that identifies the space in which identifiers of
064: * this entity hierarchy are unique. Might be a table name, a JNDI URL, etc.
065: *
066: * @return The root entity name.
067: */
068: public String getRootEntityName();
069:
070: /**
071: * The entity name which this persister maps.
072: *
073: * @return The name of the entity which this persister maps.
074: */
075: public String getEntityName();
076:
077: /**
078: * Retrieve the underlying entity metamodel instance...
079: *
080: *@return The metamodel
081: */
082: public EntityMetamodel getEntityMetamodel();
083:
084: /**
085: * Determine whether the given name represents a subclass entity
086: * (or this entity itself) of the entity mapped by this persister.
087: *
088: * @param entityName The entity name to be checked.
089: * @return True if the given entity name represents either the entity
090: * mapped by this persister or one of its subclass entities; false
091: * otherwise.
092: */
093: public boolean isSubclassEntityName(String entityName);
094:
095: /**
096: * Returns an array of objects that identify spaces in which properties of
097: * this entity are persisted, for instances of this class only.
098: * <p/>
099: * For most implementations, this returns the complete set of table names
100: * to which instances of the mapped entity are persisted (not accounting
101: * for superclass entity mappings).
102: *
103: * @return The property spaces.
104: */
105: public Serializable[] getPropertySpaces();
106:
107: /**
108: * Returns an array of objects that identify spaces in which properties of
109: * this entity are persisted, for instances of this class and its subclasses.
110: * <p/>
111: * Much like {@link #getPropertySpaces()}, except that here we include subclass
112: * entity spaces.
113: *
114: * @return The query spaces.
115: */
116: public Serializable[] getQuerySpaces();
117:
118: /**
119: * Determine whether this entity supports dynamic proxies.
120: *
121: * @return True if the entity has dynamic proxy support; false otherwise.
122: */
123: public boolean hasProxy();
124:
125: /**
126: * Determine whether this entity contains references to persistent collections.
127: *
128: * @return True if the entity does contain persistent collections; false otherwise.
129: */
130: public boolean hasCollections();
131:
132: /**
133: * Determine whether any properties of this entity are considered mutable.
134: *
135: * @return True if any properties of the entity are mutable; false otherwise (meaning none are).
136: */
137: public boolean hasMutableProperties();
138:
139: /**
140: * Determine whether this entity contains references to persistent collections
141: * which are fetchable by subselect?
142: *
143: * @return True if the entity contains collections fetchable by subselect; false otherwise.
144: */
145: public boolean hasSubselectLoadableCollections();
146:
147: /**
148: * Determine whether this entity has any non-none cascading.
149: *
150: * @return True if the entity has any properties with a cscade other than NONE;
151: * false otherwise (aka, no cascading).
152: */
153: public boolean hasCascades();
154:
155: /**
156: * Determine whether instances of this entity are considered mutable.
157: *
158: * @return True if the entity is considered mutable; false otherwise.
159: */
160: public boolean isMutable();
161:
162: /**
163: * Determine whether the entity is inherited one or more other entities.
164: * In other words, is this entity a subclass of other entities.
165: *
166: * @return True if other entities extend this entity; false otherwise.
167: */
168: public boolean isInherited();
169:
170: /**
171: * Are identifiers of this entity assigned known before the insert execution?
172: * Or, are they generated (in the database) by the insert execution.
173: *
174: * @return True if identifiers for this entity are generated by the insert
175: * execution.
176: */
177: public boolean isIdentifierAssignedByInsert();
178:
179: /**
180: * Get the type of a particular property by name.
181: *
182: * @param propertyName The name of the property for which to retrieve
183: * the typpe.
184: * @return The type.
185: * @throws org.hibernate.MappingException Typically indicates an unknown
186: * property name.
187: */
188: public Type getPropertyType(String propertyName)
189: throws MappingException;
190:
191: /**
192: * Compare the two snapshots to determine if they represent dirty state.
193: *
194: * @param currentState The current snapshot
195: * @param previousState The baseline snapshot
196: * @param owner The entity containing the state
197: * @param session The originating session
198: * @return The indices of all dirty properties, or null if no properties
199: * were dirty.
200: */
201: public int[] findDirty(Object[] currentState,
202: Object[] previousState, Object owner,
203: SessionImplementor session);
204:
205: /**
206: * Compare the two snapshots to determine if they represent modified state.
207: *
208: * @param old The baseline snapshot
209: * @param current The current snapshot
210: * @param object The entity containing the state
211: * @param session The originating session
212: * @return The indices of all modified properties, or null if no properties
213: * were modified.
214: */
215: public int[] findModified(Object[] old, Object[] current,
216: Object object, SessionImplementor session);
217:
218: /**
219: * Determine whether the entity has a particular property holding
220: * the identifier value.
221: *
222: * @return True if the entity has a specific property holding identifier value.
223: */
224: public boolean hasIdentifierProperty();
225:
226: /**
227: * Determine whether detahced instances of this entity carry their own
228: * identifier value.
229: * <p/>
230: * The other option is the deperecated feature where users could supply
231: * the id during session calls.
232: *
233: * @return True if either (1) {@link #hasIdentifierProperty()} or
234: * (2) the identifier is an embedded composite identifier; false otherwise.
235: */
236: public boolean canExtractIdOutOfEntity();
237:
238: /**
239: * Determine whether optimistic locking by column is enabled for this
240: * entity.
241: *
242: * @return True if optimistic locking by column (i.e., <version/> or
243: * <timestamp/>) is enabled; false otherwise.
244: */
245: public boolean isVersioned();
246:
247: /**
248: * If {@link #isVersioned()}, then what is the type of the property
249: * holding the locking value.
250: *
251: * @return The type of the version property; or null, if not versioned.
252: */
253: public VersionType getVersionType();
254:
255: /**
256: * If {@link #isVersioned()}, then what is the index of the property
257: * holding the locking value.
258: *
259: * @return The type of the version property; or -66, if not versioned.
260: */
261: public int getVersionProperty();
262:
263: /**
264: * Determine whether this entity defines a natural identifier.
265: *
266: * @return True if the entity defines a natural id; false otherwise.
267: */
268: public boolean hasNaturalIdentifier();
269:
270: /**
271: * If the entity defines a natural id ({@link #hasNaturalIdentifier()}), which
272: * properties make up the natural id.
273: *
274: * @return The indices of the properties making of the natural id; or
275: * null, if no natural id is defined.
276: */
277: public int[] getNaturalIdentifierProperties();
278:
279: /**
280: * Retrieve the current state of the natural-id properties from the database.
281: *
282: * @param id The identifier of the entity for which to retrieve the naturak-id values.
283: * @param session The session from which the request originated.
284: * @return The natural-id snapshot.
285: */
286: public Object[] getNaturalIdentifierSnapshot(Serializable id,
287: SessionImplementor session);
288:
289: /**
290: * Determine which identifier generation strategy is used for this entity.
291: *
292: * @return The identifier generation strategy.
293: */
294: public IdentifierGenerator getIdentifierGenerator();
295:
296: /**
297: * Determine whether this entity defines any lazy properties (ala
298: * bytecode instrumentation).
299: *
300: * @return True if the entity has properties mapped as lazy; false otherwise.
301: */
302: public boolean hasLazyProperties();
303:
304: /**
305: * Load an instance of the persistent class.
306: */
307: public Object load(Serializable id, Object optionalObject,
308: LockMode lockMode, SessionImplementor session)
309: throws HibernateException;
310:
311: /**
312: * Do a version check (optional operation)
313: */
314: public void lock(Serializable id, Object version, Object object,
315: LockMode lockMode, SessionImplementor session)
316: throws HibernateException;
317:
318: /**
319: * Persist an instance
320: */
321: public void insert(Serializable id, Object[] fields, Object object,
322: SessionImplementor session) throws HibernateException;
323:
324: /**
325: * Persist an instance, using a natively generated identifier (optional operation)
326: */
327: public Serializable insert(Object[] fields, Object object,
328: SessionImplementor session) throws HibernateException;
329:
330: /**
331: * Delete a persistent instance
332: */
333: public void delete(Serializable id, Object version, Object object,
334: SessionImplementor session) throws HibernateException;
335:
336: /**
337: * Update a persistent instance
338: */
339: public void update(Serializable id, Object[] fields,
340: int[] dirtyFields, boolean hasDirtyCollection,
341: Object[] oldFields, Object oldVersion, Object object,
342: Object rowId, SessionImplementor session)
343: throws HibernateException;
344:
345: /**
346: * Get the Hibernate types of the class properties
347: */
348: public Type[] getPropertyTypes();
349:
350: /**
351: * Get the names of the class properties - doesn't have to be the names of the
352: * actual Java properties (used for XML generation only)
353: */
354: public String[] getPropertyNames();
355:
356: /**
357: * Get the "insertability" of the properties of this class
358: * (does the property appear in an SQL INSERT)
359: */
360: public boolean[] getPropertyInsertability();
361:
362: /**
363: * Which of the properties of this class are database generated values on insert?
364: */
365: public ValueInclusion[] getPropertyInsertGenerationInclusions();
366:
367: /**
368: * Which of the properties of this class are database generated values on update?
369: */
370: public ValueInclusion[] getPropertyUpdateGenerationInclusions();
371:
372: /**
373: * Get the "updateability" of the properties of this class
374: * (does the property appear in an SQL UPDATE)
375: */
376: public boolean[] getPropertyUpdateability();
377:
378: /**
379: * Get the "checkability" of the properties of this class
380: * (is the property dirty checked, does the cache need
381: * to be updated)
382: */
383: public boolean[] getPropertyCheckability();
384:
385: /**
386: * Get the nullability of the properties of this class
387: */
388: public boolean[] getPropertyNullability();
389:
390: /**
391: * Get the "versionability" of the properties of this class
392: * (is the property optimistic-locked)
393: */
394: public boolean[] getPropertyVersionability();
395:
396: public boolean[] getPropertyLaziness();
397:
398: /**
399: * Get the cascade styles of the propertes (optional operation)
400: */
401: public CascadeStyle[] getPropertyCascadeStyles();
402:
403: /**
404: * Get the identifier type
405: */
406: public Type getIdentifierType();
407:
408: /**
409: * Get the name of the identifier property (or return null) - need not return the
410: * name of an actual Java property
411: */
412: public String getIdentifierPropertyName();
413:
414: /**
415: * Should we always invalidate the cache instead of
416: * recaching updated state
417: */
418: public boolean isCacheInvalidationRequired();
419:
420: /**
421: * Should lazy properties of this entity be cached?
422: */
423: public boolean isLazyPropertiesCacheable();
424:
425: /**
426: * Does this class have a cache.
427: */
428: public boolean hasCache();
429:
430: /**
431: * Get the cache (optional operation)
432: */
433: public CacheConcurrencyStrategy getCache();
434:
435: /**
436: * Get the cache structure
437: */
438: public CacheEntryStructure getCacheEntryStructure();
439:
440: /**
441: * Get the user-visible metadata for the class (optional operation)
442: */
443: public ClassMetadata getClassMetadata();
444:
445: /**
446: * Is batch loading enabled?
447: */
448: public boolean isBatchLoadable();
449:
450: /**
451: * Is select snapshot before update enabled?
452: */
453: public boolean isSelectBeforeUpdateRequired();
454:
455: /**
456: * Get the current database state of the object, in a "hydrated" form, without
457: * resolving identifiers
458: * @return null if there is no row in the database
459: */
460: public Object[] getDatabaseSnapshot(Serializable id,
461: SessionImplementor session) throws HibernateException;
462:
463: /**
464: * Get the current version of the object, or return null if there is no row for
465: * the given identifier. In the case of unversioned data, return any object
466: * if the row exists.
467: */
468: public Object getCurrentVersion(Serializable id,
469: SessionImplementor session) throws HibernateException;
470:
471: public Object forceVersionIncrement(Serializable id,
472: Object currentVersion, SessionImplementor session)
473: throws HibernateException;
474:
475: /**
476: * Try to discover the entity mode from the entity instance
477: */
478: public EntityMode guessEntityMode(Object object);
479:
480: /**
481: * Has the class actually been bytecode instrumented?
482: */
483: public boolean isInstrumented(EntityMode entityMode);
484:
485: /**
486: * Does this entity define any properties as being database generated on insert?
487: *
488: * @return True if this entity contains at least one property defined
489: * as generated (including version property, but not identifier).
490: */
491: public boolean hasInsertGeneratedProperties();
492:
493: /**
494: * Does this entity define any properties as being database generated on update?
495: *
496: * @return True if this entity contains at least one property defined
497: * as generated (including version property, but not identifier).
498: */
499: public boolean hasUpdateGeneratedProperties();
500:
501: /**
502: * Does this entity contain a version property that is defined
503: * to be database generated?
504: *
505: * @return true if this entity contains a version property and that
506: * property has been marked as generated.
507: */
508: public boolean isVersionPropertyGenerated();
509:
510: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
511: // stuff that is tuplizer-centric, but is passed a session ~~~~~~~~~~~~~~~~
512: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
513:
514: /**
515: * Called just after the entities properties have been initialized
516: */
517: public void afterInitialize(Object entity,
518: boolean lazyPropertiesAreUnfetched,
519: SessionImplementor session);
520:
521: /**
522: * Called just after the entity has been reassociated with the session
523: */
524: public void afterReassociate(Object entity,
525: SessionImplementor session);
526:
527: /**
528: * Create a new proxy instance
529: */
530: public Object createProxy(Serializable id,
531: SessionImplementor session) throws HibernateException;
532:
533: /**
534: * Is this a new transient instance?
535: */
536: public Boolean isTransient(Object object, SessionImplementor session)
537: throws HibernateException;
538:
539: /**
540: * Return the values of the insertable properties of the object (including backrefs)
541: */
542: public Object[] getPropertyValuesToInsert(Object object,
543: Map mergeMap, SessionImplementor session)
544: throws HibernateException;
545:
546: /**
547: * Perform a select to retrieve the values of any generated properties
548: * back from the database, injecting these generated values into the
549: * given entity as well as writing this state to the
550: * {@link org.hibernate.engine.PersistenceContext}.
551: * <p/>
552: * Note, that because we update the PersistenceContext here, callers
553: * need to take care that they have already written the initial snapshot
554: * to the PersistenceContext before calling this method.
555: *
556: * @param id The entity's id value.
557: * @param entity The entity for which to get the state.
558: * @param state
559: * @param session The session
560: */
561: public void processInsertGeneratedProperties(Serializable id,
562: Object entity, Object[] state, SessionImplementor session);
563:
564: /**
565: * Perform a select to retrieve the values of any generated properties
566: * back from the database, injecting these generated values into the
567: * given entity as well as writing this state to the
568: * {@link org.hibernate.engine.PersistenceContext}.
569: * <p/>
570: * Note, that because we update the PersistenceContext here, callers
571: * need to take care that they have already written the initial snapshot
572: * to the PersistenceContext before calling this method.
573: *
574: * @param id The entity's id value.
575: * @param entity The entity for which to get the state.
576: * @param state
577: * @param session The session
578: */
579: public void processUpdateGeneratedProperties(Serializable id,
580: Object entity, Object[] state, SessionImplementor session);
581:
582: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
583: // stuff that is Tuplizer-centric ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
584: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
585:
586: /**
587: * The persistent class, or null
588: */
589: public Class getMappedClass(EntityMode entityMode);
590:
591: /**
592: * Does the class implement the <tt>Lifecycle</tt> interface.
593: */
594: public boolean implements Lifecycle(EntityMode entityMode);
595:
596: /**
597: * Does the class implement the <tt>Validatable</tt> interface.
598: */
599: public boolean implements Validatable(EntityMode entityMode);
600:
601: /**
602: * Get the proxy interface that instances of <em>this</em> concrete class will be
603: * cast to (optional operation).
604: */
605: public Class getConcreteProxyClass(EntityMode entityMode);
606:
607: /**
608: * Set the given values to the mapped properties of the given object
609: */
610: public void setPropertyValues(Object object, Object[] values,
611: EntityMode entityMode) throws HibernateException;
612:
613: /**
614: * Set the value of a particular property
615: */
616: public void setPropertyValue(Object object, int i, Object value,
617: EntityMode entityMode) throws HibernateException;
618:
619: /**
620: * Return the (loaded) values of the mapped properties of the object (not including backrefs)
621: */
622: public Object[] getPropertyValues(Object object,
623: EntityMode entityMode) throws HibernateException;
624:
625: /**
626: * Get the value of a particular property
627: */
628: public Object getPropertyValue(Object object, int i,
629: EntityMode entityMode) throws HibernateException;
630:
631: /**
632: * Get the value of a particular property
633: */
634: public Object getPropertyValue(Object object, String propertyName,
635: EntityMode entityMode) throws HibernateException;
636:
637: /**
638: * Get the identifier of an instance (throw an exception if no identifier property)
639: */
640: public Serializable getIdentifier(Object object,
641: EntityMode entityMode) throws HibernateException;
642:
643: /**
644: * Set the identifier of an instance (or do nothing if no identifier property)
645: */
646: public void setIdentifier(Object object, Serializable id,
647: EntityMode entityMode) throws HibernateException;
648:
649: /**
650: * Get the version number (or timestamp) from the object's version property (or return null if not versioned)
651: */
652: public Object getVersion(Object object, EntityMode entityMode)
653: throws HibernateException;
654:
655: /**
656: * Create a class instance initialized with the given identifier
657: */
658: public Object instantiate(Serializable id, EntityMode entityMode)
659: throws HibernateException;
660:
661: /**
662: * Is the given object an instance of this entity?
663: */
664: public boolean isInstance(Object object, EntityMode entityMode);
665:
666: /**
667: * Does the given instance have any uninitialized lazy properties?
668: */
669: public boolean hasUninitializedLazyProperties(Object object,
670: EntityMode entityMode);
671:
672: /**
673: * Set the identifier and version of the given instance back
674: * to its "unsaved" value, returning the id
675: * @param currentId TODO
676: * @param currentVersion TODO
677: */
678: public void resetIdentifier(Object entity, Serializable currentId,
679: Object currentVersion, EntityMode entityMode);
680:
681: /**
682: * Get the persister for an instance of this class or a subclass
683: */
684: public EntityPersister getSubclassEntityPersister(Object instance,
685: SessionFactoryImplementor factory, EntityMode entityMode);
686: }
|