KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > type > EntityType


1 //$Id: EntityType.java,v 1.51 2005/07/21 01:11:52 oneovthafew Exp $
2
package org.hibernate.type;
3
4 import java.io.Serializable JavaDoc;
5 import java.sql.ResultSet JavaDoc;
6 import java.sql.SQLException JavaDoc;
7 import java.util.Map JavaDoc;
8
9 import org.dom4j.Element;
10 import org.dom4j.Node;
11 import org.hibernate.AssertionFailure;
12 import org.hibernate.EntityMode;
13 import org.hibernate.HibernateException;
14 import org.hibernate.MappingException;
15 import org.hibernate.engine.EntityUniqueKey;
16 import org.hibernate.engine.ForeignKeys;
17 import org.hibernate.engine.Mapping;
18 import org.hibernate.engine.PersistenceContext;
19 import org.hibernate.engine.SessionFactoryImplementor;
20 import org.hibernate.engine.SessionImplementor;
21 import org.hibernate.persister.entity.EntityPersister;
22 import org.hibernate.persister.entity.Joinable;
23 import org.hibernate.persister.entity.UniqueKeyLoadable;
24 import org.hibernate.proxy.HibernateProxy;
25 import org.hibernate.proxy.LazyInitializer;
26 import org.hibernate.tuple.ElementWrapper;
27 import org.hibernate.util.ReflectHelper;
28
29 /**
30  * A reference to an entity class
31  * @author Gavin King
32  */

33 public abstract class EntityType extends AbstractType implements AssociationType {
34
35     private final String JavaDoc associatedEntityName;
36     protected final String JavaDoc uniqueKeyPropertyName;
37     protected final boolean isEmbeddedInXML;
38     private final boolean eager;
39     private final boolean unwrapProxy;
40     
41     public boolean isEmbeddedInXML() {
42         return isEmbeddedInXML;
43     }
44     
45     public final boolean isEntityType() {
46         return true;
47     }
48     
49     public String JavaDoc getPropertyName() {
50         return null;
51     }
52
53     public final String JavaDoc getAssociatedEntityName() {
54         return associatedEntityName;
55     }
56
57     public final boolean isSame(Object JavaDoc x, Object JavaDoc y, EntityMode entityMode) {
58         return x==y;
59     }
60     
61     public int compare(Object JavaDoc x, Object JavaDoc y, EntityMode entityMode) {
62         return 0; //TODO: entities CAN be compared, by PK, fix this!
63
}
64
65     protected EntityType(
66             String JavaDoc entityName,
67             String JavaDoc uniqueKeyPropertyName,
68             boolean eager,
69             boolean isEmbeddedInXML,
70             boolean unwrapProxy
71     ) {
72         this.associatedEntityName = entityName;
73         this.uniqueKeyPropertyName = uniqueKeyPropertyName;
74         this.isEmbeddedInXML = isEmbeddedInXML;
75         this.eager = eager;
76         this.unwrapProxy = unwrapProxy;
77     }
78
79     public Object JavaDoc nullSafeGet(ResultSet JavaDoc rs, String JavaDoc name, SessionImplementor session, Object JavaDoc owner)
80     throws HibernateException, SQLException JavaDoc {
81         return nullSafeGet( rs, new String JavaDoc[] {name}, session, owner );
82     }
83
84     /**
85      * This returns the wrong class for an entity with a proxy. Theoretically
86      * it should return the proxy class, but it doesn't.
87      */

88     public final Class JavaDoc getReturnedClass() {
89         try {
90             return ReflectHelper.classForName(associatedEntityName);
91         }
92         catch (ClassNotFoundException JavaDoc cnfe) {
93             return java.util.Map JavaDoc.class;
94         }
95     }
96
97     /*protected final Object getActualIdentifier(Object value, SessionImplementor session) throws HibernateException {
98         return session.getEntityIdentifierIfNotUnsaved(value); //tolerates nulls
99     }*/

100
101     protected final Object JavaDoc getIdentifier(Object JavaDoc value, SessionImplementor session)
102     throws HibernateException {
103
104         if ( isNotEmbedded(session) ) return value;
105         
106         if ( isReferenceToPrimaryKey() ) {
107             return ForeignKeys.getEntityIdentifierIfNotUnsaved(associatedEntityName, value, session); //tolerates nulls
108
}
109         else if (value==null) {
110             return null;
111         }
112         else {
113             return session.getFactory()
114                     .getEntityPersister( getAssociatedEntityName() )
115                     .getPropertyValue( value, uniqueKeyPropertyName, session.getEntityMode() );
116         }
117     }
118
119     protected boolean isNotEmbedded(SessionImplementor session) {
120         return !isEmbeddedInXML && session.getEntityMode()==EntityMode.DOM4J;
121     }
122
123     /**
124      * Get the identifier value of an instance or proxy
125      */

126     private static Serializable JavaDoc getIdentifier(Object JavaDoc object, EntityPersister persister, EntityMode entityMode)
127     throws HibernateException {
128         if (object instanceof HibernateProxy) {
129             HibernateProxy proxy = (HibernateProxy) object;
130             LazyInitializer li = proxy.getHibernateLazyInitializer();
131             return li.getIdentifier();
132         }
133         else {
134             return persister.getIdentifier( object, entityMode );
135         }
136     }
137     
138     public String JavaDoc toLoggableString(Object JavaDoc value, SessionFactoryImplementor factory)
139     throws HibernateException {
140
141         if (value==null) return "null";
142         
143         EntityPersister persister = factory.getEntityPersister(associatedEntityName);
144         StringBuffer JavaDoc result = new StringBuffer JavaDoc()
145             .append(associatedEntityName);
146         
147         if ( persister.hasIdentifierProperty() ) {
148             //TODO: use of a guess here is bad...
149
final EntityMode entityMode = persister.guessEntityMode(value);
150             final Serializable JavaDoc id;
151             if (entityMode==null) {
152                 if ( isEmbeddedInXML ) {
153                     throw new ClassCastException JavaDoc( value.getClass().getName() );
154                 }
155                 id = (Serializable JavaDoc) value;
156             }
157             else {
158                 id = getIdentifier( value, persister, entityMode );
159             }
160             
161             result.append('#')
162                 .append( persister.getIdentifierType().toLoggableString(id, factory) );
163         }
164         
165         return result.toString();
166     }
167     
168     /*public String toXMLString(Object value, SessionFactoryImplementor factory) throws HibernateException {
169         if (isEmbeddedInXML) throw new UnsupportedOperationException("entity references cannot be stringified");
170         if (factory==null) throw new AssertionFailure("null factory passed to toString");
171         return getIdentifierType(factory).toXMLString(value, factory);
172     }
173
174     public Object fromXMLString(String xml, Mapping factory) throws HibernateException {
175         if (isEmbeddedInXML) throw new UnsupportedOperationException("entity references cannot be stringified");
176         if (factory==null) throw new AssertionFailure("null factory passed to fromString");
177         return getIdentifierType(factory).fromXMLString(xml, factory);
178     }*/

179
180     public String JavaDoc getName() { return associatedEntityName; }
181
182     public Object JavaDoc deepCopy(Object JavaDoc value, EntityMode entityMode, SessionFactoryImplementor factory) {
183         return value; //special case ... this is the leaf of the containment graph, even though not immutable
184
}
185
186     public boolean isMutable() {
187         return false;
188     }
189
190     public abstract boolean isOneToOne();
191
192     public Object JavaDoc replace(Object JavaDoc original, Object JavaDoc target, SessionImplementor session, Object JavaDoc owner, Map JavaDoc copyCache)
193     throws HibernateException {
194         if (original==null) return null;
195         Object JavaDoc cached = copyCache.get(original);
196         if (cached!=null) {
197             return cached;
198         }
199         else {
200             if (original==target) return target;
201             //TODO: can this ever get called????
202
Object JavaDoc id = getIdentifier(original, session);
203             if (id==null) throw new AssertionFailure("cannot copy a reference to an object with a null id");
204             id = getIdentifierOrUniqueKeyType( session.getFactory() )
205                     .replace(id, null, session, owner, copyCache);
206             return resolve(id, session, owner);
207         }
208     }
209
210     public boolean isAssociationType() {
211         return true;
212     }
213
214     public final Object JavaDoc nullSafeGet(ResultSet JavaDoc rs, String JavaDoc[] names, SessionImplementor session, Object JavaDoc owner)
215     throws HibernateException, SQLException JavaDoc {
216         return resolve( hydrate(rs, names, session, owner), session, owner );
217     }
218
219     public boolean isDirty(Object JavaDoc old, Object JavaDoc current, SessionImplementor session)
220     throws HibernateException {
221
222         if ( isSame( old, current, session.getEntityMode() ) ) return false;
223
224         Object JavaDoc oldid = getIdentifier(old, session);
225         Object JavaDoc newid = getIdentifier(current, session);
226         return !getIdentifierType(session).isSame( oldid, newid, session.getEntityMode() );
227
228     }
229
230     public Joinable getAssociatedJoinable(SessionFactoryImplementor factory)
231     throws MappingException {
232         return (Joinable) factory.getEntityPersister(associatedEntityName);
233     }
234     
235     Type getIdentifierType(Mapping factory) {
236         return factory.getIdentifierType( getAssociatedEntityName() );
237     }
238
239     Type getIdentifierType(SessionImplementor session) throws MappingException {
240         return getIdentifierType( session.getFactory() );
241     }
242
243     public final Type getIdentifierOrUniqueKeyType(Mapping factory)
244     throws MappingException {
245         if ( isReferenceToPrimaryKey() ) {
246             return getIdentifierType(factory);
247         }
248         else {
249             return factory.getReferencedPropertyType( getAssociatedEntityName(), uniqueKeyPropertyName );
250         }
251     }
252
253     public final String JavaDoc getIdentifierOrUniqueKeyPropertyName(Mapping factory)
254     throws MappingException {
255         if ( isReferenceToPrimaryKey() ) {
256             return factory.getIdentifierPropertyName( getAssociatedEntityName() );
257         }
258         else {
259             return uniqueKeyPropertyName;
260         }
261     }
262     
263     protected abstract boolean isNullable();
264
265     /**
266      * Resolve an identifier
267      */

268     protected final Object JavaDoc resolveIdentifier(Serializable JavaDoc id, SessionImplementor session)
269     throws HibernateException {
270         Object JavaDoc proxyOrEntity = session.internalLoad(
271                 getAssociatedEntityName(),
272                 id,
273                 eager,
274                 isNullable()
275             );
276         if (proxyOrEntity instanceof HibernateProxy) {
277             ( (HibernateProxy) proxyOrEntity ).getHibernateLazyInitializer()
278                     .setUnwrap(unwrapProxy);
279         }
280         return proxyOrEntity;
281     }
282
283     protected boolean isNull(Object JavaDoc owner, SessionImplementor session) {
284         return false;
285     }
286     
287     /**
288      * Resolve an identifier or unique key value
289      */

290     public Object JavaDoc resolve(Object JavaDoc value, SessionImplementor session, Object JavaDoc owner)
291     throws HibernateException {
292         
293         if ( isNotEmbedded(session) ) {
294             return value;
295         }
296
297         if (value==null) {
298             return null;
299         }
300         else {
301             
302             if ( isNull(owner, session) ) return null; //EARLY EXIT!
303

304             if ( isReferenceToPrimaryKey() ) {
305                 return resolveIdentifier( (Serializable JavaDoc) value, session );
306             }
307             else {
308                 return loadByUniqueKey(
309                         getAssociatedEntityName(),
310                         uniqueKeyPropertyName,
311                         value,
312                         session
313                     );
314             }
315         }
316     }
317
318     public String JavaDoc getAssociatedEntityName(SessionFactoryImplementor factory) {
319         return getAssociatedEntityName();
320     }
321
322     /**
323      * Does this association foreign key reference the
324      * primary key of the other table?
325      */

326     public boolean isReferenceToPrimaryKey() {
327         return uniqueKeyPropertyName==null;
328     }
329     
330     public String JavaDoc getRHSUniqueKeyPropertyName() {
331         return uniqueKeyPropertyName;
332     }
333
334     public String JavaDoc toString() {
335         return getClass().getName() + '(' + getAssociatedEntityName() + ')';
336     }
337
338     /**
339      * Load an instance by a unique key that is not the primary key.
340      */

341     public Object JavaDoc loadByUniqueKey(
342             String JavaDoc entityName,
343             String JavaDoc uniqueKeyPropertyName,
344             Object JavaDoc key,
345             SessionImplementor session)
346     throws HibernateException {
347         
348         final SessionFactoryImplementor factory = session.getFactory();
349         
350         UniqueKeyLoadable persister = (UniqueKeyLoadable) factory.getEntityPersister(entityName);
351             
352         //TODO: implement caching?! proxies?!
353

354         EntityUniqueKey euk = new EntityUniqueKey(
355                 entityName,
356                 uniqueKeyPropertyName,
357                 key,
358                 getIdentifierOrUniqueKeyType( factory ),
359                 session.getEntityMode(),
360                 session.getFactory()
361         );
362         
363         final PersistenceContext persistenceContext = session.getPersistenceContext();
364         Object JavaDoc result = persistenceContext.getEntity(euk);
365         //if ( result==null && !persistenceContext.isNonExistant(euk) ) {
366
if ( result==null ) {
367             result = persister.loadByUniqueKey(uniqueKeyPropertyName, key, session);
368         }
369         return result==null ? null : persistenceContext.proxyFor(result);
370         
371     }
372
373     public String JavaDoc getLHSPropertyName() {
374         return null;
375     }
376
377     public String JavaDoc getOnCondition(String JavaDoc alias, SessionFactoryImplementor factory, Map JavaDoc enabledFilters)
378     throws MappingException {
379         if ( isReferenceToPrimaryKey() ) { //TODO: this is a bit arbitrary, expose a switch to the user?
380
return "";
381         }
382         else {
383             return getAssociatedJoinable(factory).filterFragment(alias, enabledFilters);
384         }
385     }
386     
387     public Type getSemiResolvedType(SessionFactoryImplementor factory) {
388         return factory.getEntityPersister(associatedEntityName).getIdentifierType();
389     }
390     
391     public int getHashCode(Object JavaDoc x, EntityMode entityMode, SessionFactoryImplementor factory) {
392         EntityPersister persister = factory.getEntityPersister(associatedEntityName);
393         if ( !persister.hasIdentifierPropertyOrEmbeddedCompositeIdentifier() ) {
394             return super.getHashCode(x, entityMode);
395         }
396         
397         if (x instanceof HibernateProxy) {
398             return ( (HibernateProxy) x ).getHibernateLazyInitializer().getIdentifier().hashCode();
399         }
400         
401         Serializable JavaDoc id = persister.getIdentifier(x, entityMode);
402         return persister.getIdentifierType().getHashCode(id, entityMode, factory);
403     }
404     
405     public boolean isEqual(Object JavaDoc x, Object JavaDoc y, EntityMode entityMode, SessionFactoryImplementor factory) {
406         EntityPersister persister = factory.getEntityPersister(associatedEntityName);
407         if ( !persister.hasIdentifierPropertyOrEmbeddedCompositeIdentifier() ) {
408             return super.isEqual(x, y, entityMode);
409         }
410         
411         Serializable JavaDoc xid;
412         if (x instanceof HibernateProxy) {
413             xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
414                     .getIdentifier();
415         }
416         else {
417             xid = persister.getIdentifier(x, entityMode);
418         }
419         
420         Serializable JavaDoc yid;
421         if (y instanceof HibernateProxy) {
422             yid = ( (HibernateProxy) y ).getHibernateLazyInitializer()
423                     .getIdentifier();
424         }
425         else {
426             yid = persister.getIdentifier(y, entityMode);
427         }
428         
429         return persister.getIdentifierType()
430                 .isEqual(xid, yid, entityMode, factory);
431     }
432
433     public boolean isXMLElement() {
434         return isEmbeddedInXML;
435     }
436
437     public Object JavaDoc fromXMLNode(Node xml, Mapping factory) throws HibernateException {
438         if ( !isEmbeddedInXML ) {
439             return getIdentifierType(factory).fromXMLNode(xml, factory);
440         }
441         else {
442             return xml;
443         }
444     }
445
446     public void setToXMLNode(Node node, Object JavaDoc value, SessionFactoryImplementor factory)
447     throws HibernateException {
448         if ( !isEmbeddedInXML ) {
449             getIdentifierType(factory).setToXMLNode(node, value, factory);
450         }
451         else {
452             Element elt = (Element) value;
453             replaceNode( node, new ElementWrapper(elt) );
454         }
455     }
456
457 }
458
Popular Tags