1 package org.hibernate.type; 3 4 import java.io.Serializable ; 5 import java.sql.ResultSet ; 6 import java.sql.SQLException ; 7 import java.util.Map ; 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 33 public abstract class EntityType extends AbstractType implements AssociationType { 34 35 private final String associatedEntityName; 36 protected final String 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 getPropertyName() { 50 return null; 51 } 52 53 public final String getAssociatedEntityName() { 54 return associatedEntityName; 55 } 56 57 public final boolean isSame(Object x, Object y, EntityMode entityMode) { 58 return x==y; 59 } 60 61 public int compare(Object x, Object y, EntityMode entityMode) { 62 return 0; } 64 65 protected EntityType( 66 String entityName, 67 String 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 nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) 80 throws HibernateException, SQLException { 81 return nullSafeGet( rs, new String [] {name}, session, owner ); 82 } 83 84 88 public final Class getReturnedClass() { 89 try { 90 return ReflectHelper.classForName(associatedEntityName); 91 } 92 catch (ClassNotFoundException cnfe) { 93 return java.util.Map .class; 94 } 95 } 96 97 100 101 protected final Object getIdentifier(Object value, SessionImplementor session) 102 throws HibernateException { 103 104 if ( isNotEmbedded(session) ) return value; 105 106 if ( isReferenceToPrimaryKey() ) { 107 return ForeignKeys.getEntityIdentifierIfNotUnsaved(associatedEntityName, value, session); } 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 126 private static Serializable getIdentifier(Object 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 toLoggableString(Object value, SessionFactoryImplementor factory) 139 throws HibernateException { 140 141 if (value==null) return "null"; 142 143 EntityPersister persister = factory.getEntityPersister(associatedEntityName); 144 StringBuffer result = new StringBuffer () 145 .append(associatedEntityName); 146 147 if ( persister.hasIdentifierProperty() ) { 148 final EntityMode entityMode = persister.guessEntityMode(value); 150 final Serializable id; 151 if (entityMode==null) { 152 if ( isEmbeddedInXML ) { 153 throw new ClassCastException ( value.getClass().getName() ); 154 } 155 id = (Serializable ) 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 179 180 public String getName() { return associatedEntityName; } 181 182 public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) { 183 return value; } 185 186 public boolean isMutable() { 187 return false; 188 } 189 190 public abstract boolean isOneToOne(); 191 192 public Object replace(Object original, Object target, SessionImplementor session, Object owner, Map copyCache) 193 throws HibernateException { 194 if (original==null) return null; 195 Object cached = copyCache.get(original); 196 if (cached!=null) { 197 return cached; 198 } 199 else { 200 if (original==target) return target; 201 Object 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 nullSafeGet(ResultSet rs, String [] names, SessionImplementor session, Object owner) 215 throws HibernateException, SQLException { 216 return resolve( hydrate(rs, names, session, owner), session, owner ); 217 } 218 219 public boolean isDirty(Object old, Object current, SessionImplementor session) 220 throws HibernateException { 221 222 if ( isSame( old, current, session.getEntityMode() ) ) return false; 223 224 Object oldid = getIdentifier(old, session); 225 Object 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 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 268 protected final Object resolveIdentifier(Serializable id, SessionImplementor session) 269 throws HibernateException { 270 Object 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 owner, SessionImplementor session) { 284 return false; 285 } 286 287 290 public Object resolve(Object value, SessionImplementor session, Object 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; 304 if ( isReferenceToPrimaryKey() ) { 305 return resolveIdentifier( (Serializable ) value, session ); 306 } 307 else { 308 return loadByUniqueKey( 309 getAssociatedEntityName(), 310 uniqueKeyPropertyName, 311 value, 312 session 313 ); 314 } 315 } 316 } 317 318 public String getAssociatedEntityName(SessionFactoryImplementor factory) { 319 return getAssociatedEntityName(); 320 } 321 322 326 public boolean isReferenceToPrimaryKey() { 327 return uniqueKeyPropertyName==null; 328 } 329 330 public String getRHSUniqueKeyPropertyName() { 331 return uniqueKeyPropertyName; 332 } 333 334 public String toString() { 335 return getClass().getName() + '(' + getAssociatedEntityName() + ')'; 336 } 337 338 341 public Object loadByUniqueKey( 342 String entityName, 343 String uniqueKeyPropertyName, 344 Object key, 345 SessionImplementor session) 346 throws HibernateException { 347 348 final SessionFactoryImplementor factory = session.getFactory(); 349 350 UniqueKeyLoadable persister = (UniqueKeyLoadable) factory.getEntityPersister(entityName); 351 352 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 result = persistenceContext.getEntity(euk); 365 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 getLHSPropertyName() { 374 return null; 375 } 376 377 public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) 378 throws MappingException { 379 if ( isReferenceToPrimaryKey() ) { 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 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 id = persister.getIdentifier(x, entityMode); 402 return persister.getIdentifierType().getHashCode(id, entityMode, factory); 403 } 404 405 public boolean isEqual(Object x, Object 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 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 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 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 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 |