1 package org.hibernate.engine; 3 4 import java.io.IOException ; 5 import java.io.InvalidObjectException ; 6 import java.io.ObjectInputStream ; 7 import java.io.ObjectOutputStream ; 8 import java.io.Serializable ; 9 import java.util.ArrayList ; 10 import java.util.HashMap ; 11 import java.util.HashSet ; 12 import java.util.Iterator ; 13 import java.util.List ; 14 import java.util.Map ; 15 16 import org.apache.commons.collections.ReferenceMap; 17 import org.apache.commons.logging.Log; 18 import org.apache.commons.logging.LogFactory; 19 import org.hibernate.AssertionFailure; 20 import org.hibernate.Hibernate; 21 import org.hibernate.HibernateException; 22 import org.hibernate.LockMode; 23 import org.hibernate.MappingException; 24 import org.hibernate.NonUniqueObjectException; 25 import org.hibernate.PersistentObjectException; 26 import org.hibernate.TransientObjectException; 27 import org.hibernate.collection.PersistentCollection; 28 import org.hibernate.persister.collection.CollectionPersister; 29 import org.hibernate.persister.entity.EntityPersister; 30 import org.hibernate.proxy.HibernateProxy; 31 import org.hibernate.proxy.LazyInitializer; 32 import org.hibernate.tuple.ElementWrapper; 33 import org.hibernate.util.IdentityMap; 34 import org.hibernate.util.MarkerObject; 35 36 48 public class StatefulPersistenceContext implements Serializable , PersistenceContext { 49 50 53 private static final Log log = LogFactory.getLog( StatefulPersistenceContext.class ); 54 55 public static final Object NO_ROW = new MarkerObject("NO_ROW"); 56 57 private SessionImplementor session; 58 59 private final Map entitiesByKey; 61 62 private final Map entitiesByUniqueKey; 64 65 private transient Map entityEntries; 67 68 private transient Map proxiesByKey; 70 71 private final Map entitySnapshotsByKey; 74 75 private transient Map arrayHolders; 77 78 private transient Map collectionEntries; 80 81 private final Map collectionsByKey; 84 private HashSet nullifiableEntityKeys = new HashSet (); 86 87 90 93 private transient HashSet nullAssociations; 95 96 private transient List nonlazyCollections; 99 100 private transient Map unownedCollections; 103 104 private transient int cascading = 0; 105 private transient int loadCounter = 0; 106 private transient boolean flushing = false; 107 108 private boolean hasNonReadOnlyEntities = false; 109 110 private transient CollectionLoadContext collectionLoadContext; 111 private transient BatchFetchQueue batchFetchQueue; 112 113 public boolean isStateless() { 114 return false; 115 } 116 117 public SessionImplementor getSession() { 118 return session; 119 } 120 121 public CollectionLoadContext getCollectionLoadContext() { 122 if (collectionLoadContext==null) { 123 collectionLoadContext = new CollectionLoadContext(this); 124 } 125 return collectionLoadContext; 126 } 127 128 public void addUnownedCollection(CollectionKey key, PersistentCollection collection) { 129 if (unownedCollections==null) { 130 unownedCollections = new HashMap (8); 131 } 132 unownedCollections.put(key, collection); 133 } 134 135 public PersistentCollection useUnownedCollection(CollectionKey key) { 136 if (unownedCollections==null) { 137 return null; 138 } 139 else { 140 return (PersistentCollection) unownedCollections.remove(key); 141 } 142 } 143 144 148 public BatchFetchQueue getBatchFetchQueue() { 149 if (batchFetchQueue==null) { 150 batchFetchQueue = new BatchFetchQueue(this); 151 } 152 return batchFetchQueue; 153 } 154 155 private static final int INIT_MAP_SIZE = 8; 156 157 162 public StatefulPersistenceContext(SessionImplementor session) { 163 this.session = session; 164 165 entitiesByKey = new HashMap (INIT_MAP_SIZE); 166 entitiesByUniqueKey = new HashMap (INIT_MAP_SIZE); 167 proxiesByKey = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK); 168 entitySnapshotsByKey = new HashMap (INIT_MAP_SIZE); 169 entityEntries = IdentityMap.instantiateSequenced(INIT_MAP_SIZE); 172 collectionEntries = IdentityMap.instantiateSequenced(INIT_MAP_SIZE); 173 collectionsByKey = new HashMap (INIT_MAP_SIZE); 174 arrayHolders = IdentityMap.instantiate(INIT_MAP_SIZE); 175 176 initTransientState(); 177 } 178 179 private void readObject(ObjectInputStream ois) throws IOException , ClassNotFoundException { 180 log.trace( "deserializing persistent-context" ); 181 ois.defaultReadObject(); 182 183 entityEntries = IdentityMap.deserialize( ois.readObject() ); 184 collectionEntries = IdentityMap.deserialize( ois.readObject() ); 185 arrayHolders = IdentityMap.deserialize( ois.readObject() ); 186 187 initTransientState(); 188 189 proxiesByKey = new ReferenceMap( ReferenceMap.HARD, ReferenceMap.WEAK ); 190 Map map = ( Map ) ois.readObject(); 191 proxiesByKey.putAll( map ); 192 193 197 try { 198 199 Iterator iter = collectionEntries.entrySet().iterator(); 200 while ( iter.hasNext() ) { 201 Map.Entry e = ( Map.Entry ) iter.next(); 202 ( ( PersistentCollection ) e.getKey() ).setCurrentSession( session ); 203 CollectionEntry ce = ( CollectionEntry ) e.getValue(); 204 if ( ce.getRole() != null ) { 205 ce.afterDeserialize( session.getFactory() ); 206 } 207 } 208 209 iter = proxiesByKey.values().iterator(); 210 while ( iter.hasNext() ) { 211 Object proxy = iter.next(); 212 if ( proxy instanceof HibernateProxy ) { 213 ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().setSession( session ); 214 } 215 else { 216 iter.remove(); } 218 } 219 220 iter = entityEntries.entrySet().iterator(); 221 while ( iter.hasNext() ) { 222 EntityEntry e = ( EntityEntry ) ( ( Map.Entry ) iter.next() ).getValue(); 223 e.afterDeserialize( session.getFactory() ); 224 } 225 226 } 227 catch (HibernateException he) { 228 throw new InvalidObjectException ( he.getMessage() ); 229 } 230 231 } 232 233 private void writeObject(ObjectOutputStream oos) throws IOException { 234 log.trace( "serializing persistent-context" ); 235 236 oos.defaultWriteObject(); 237 238 oos.writeObject( IdentityMap.serialize(entityEntries) ); 239 oos.writeObject( IdentityMap.serialize(collectionEntries) ); 240 oos.writeObject( IdentityMap.serialize(arrayHolders) ); 241 242 HashMap map = new HashMap (INIT_MAP_SIZE); 243 map.putAll(proxiesByKey); 244 oos.writeObject(map); 245 } 246 247 private void initTransientState() { 248 nullAssociations = new HashSet (INIT_MAP_SIZE); 249 nonlazyCollections = new ArrayList (INIT_MAP_SIZE); 250 } 251 252 public void clear() { 253 arrayHolders.clear(); 254 entitiesByKey.clear(); 255 entitiesByUniqueKey.clear(); 256 entityEntries.clear(); 257 entitySnapshotsByKey.clear(); 258 collectionsByKey.clear(); 259 collectionEntries.clear(); 260 proxiesByKey.clear(); 261 nullifiableEntityKeys.clear(); 263 if (batchFetchQueue!=null) batchFetchQueue.clear(); 265 hasNonReadOnlyEntities=false; 266 } 267 268 public boolean hasNonReadOnlyEntities() { 269 return hasNonReadOnlyEntities; 270 } 271 272 public void setEntryStatus(EntityEntry entry, Status status) { 273 entry.setStatus(status); 274 setHasNonReadOnlyEnties(status); 275 } 276 277 private void setHasNonReadOnlyEnties(Status status) { 278 if ( status==Status.DELETED || status==Status.MANAGED || status==Status.SAVING ) { 279 hasNonReadOnlyEntities = true; 280 } 281 } 282 283 public void afterTransactionCompletion() { 284 Iterator iter = entityEntries.values().iterator(); 286 while ( iter.hasNext() ) { 287 ( (EntityEntry) iter.next() ).setLockMode(LockMode.NONE); 288 } 289 } 290 291 295 public Object [] getDatabaseSnapshot(Serializable id, EntityPersister persister) 296 throws HibernateException { 297 EntityKey key = new EntityKey( id, persister, session.getEntityMode() ); 298 Object cached = entitySnapshotsByKey.get(key); 299 if (cached!=null) { 300 return cached==NO_ROW ? null : (Object []) cached; 301 } 302 else { 303 Object [] snapshot = persister.getDatabaseSnapshot( id, session ); 304 entitySnapshotsByKey.put( key, snapshot==null ? NO_ROW : snapshot ); 305 return snapshot; 306 } 307 } 308 309 public Object [] getCachedDatabaseSnapshot(EntityKey key) { 310 return (Object []) entitySnapshotsByKey.get(key); 312 } 313 314 317 318 public void addEntity(EntityKey key, Object entity) { 319 entitiesByKey.put(key, entity); 320 getBatchFetchQueue().removeBatchLoadableEntityKey(key); 321 } 322 323 327 public Object getEntity(EntityKey key) { 328 return entitiesByKey.get(key); 329 } 330 331 public boolean containsEntity(EntityKey key) { 332 return entitiesByKey.containsKey(key); 333 } 334 335 340 public Object removeEntity(EntityKey key) { 341 Object entity = entitiesByKey.remove(key); 342 Iterator iter = entitiesByUniqueKey.values().iterator(); 343 while ( iter.hasNext() ) { 344 if ( iter.next()==entity ) iter.remove(); 345 } 346 entitySnapshotsByKey.remove(key); 347 nullifiableEntityKeys.remove(key); 348 getBatchFetchQueue().removeBatchLoadableEntityKey(key); 349 getBatchFetchQueue().removeSubselect(key); 350 return entity; 351 } 352 353 356 public Object getEntity(EntityUniqueKey euk) { 357 return entitiesByUniqueKey.get(euk); 358 } 359 360 363 public void addEntity(EntityUniqueKey euk, Object entity) { 364 entitiesByUniqueKey.put(euk, entity); 365 } 366 367 373 public EntityEntry getEntry(Object entity) { 374 return (EntityEntry) entityEntries.get(entity); 375 } 376 377 380 public EntityEntry removeEntry(Object entity) { 381 return (EntityEntry) entityEntries.remove(entity); 382 } 383 384 387 public boolean isEntryFor(Object entity) { 388 return entityEntries.containsKey(entity); 389 } 390 391 394 public CollectionEntry getCollectionEntry(PersistentCollection coll) { 395 return (CollectionEntry) collectionEntries.get(coll); 396 } 397 398 401 public EntityEntry addEntity( 402 final Object entity, 403 final Status status, 404 final Object [] loadedState, 405 final EntityKey entityKey, 406 final Object version, 407 final LockMode lockMode, 408 final boolean existsInDatabase, 409 final EntityPersister persister, 410 final boolean disableVersionIncrement, 411 boolean lazyPropertiesAreUnfetched 412 ) { 413 414 addEntity( entityKey, entity ); 415 416 return addEntry( 417 entity, 418 status, 419 loadedState, 420 null, 421 entityKey.getIdentifier(), 422 version, 423 lockMode, 424 existsInDatabase, 425 persister, 426 disableVersionIncrement, 427 lazyPropertiesAreUnfetched 428 ); 429 } 430 431 432 436 public EntityEntry addEntry( 437 final Object entity, 438 final Status status, 439 final Object [] loadedState, 440 final Object rowId, 441 final Serializable id, 442 final Object version, 443 final LockMode lockMode, 444 final boolean existsInDatabase, 445 final EntityPersister persister, 446 final boolean disableVersionIncrement, 447 boolean lazyPropertiesAreUnfetched) { 448 449 EntityEntry e = new EntityEntry( 450 status, 451 loadedState, 452 rowId, 453 id, 454 version, 455 lockMode, 456 existsInDatabase, 457 persister, 458 session.getEntityMode(), 459 disableVersionIncrement, 460 lazyPropertiesAreUnfetched 461 ); 462 entityEntries.put(entity, e); 463 464 setHasNonReadOnlyEnties(status); 465 return e; 466 } 467 468 public boolean containsProxy(Object entity) { 469 return proxiesByKey.values().contains( entity ); 470 } 471 472 479 public boolean reassociateIfUninitializedProxy(Object value) throws MappingException { 480 if ( value instanceof ElementWrapper ) { 481 value = ( (ElementWrapper) value ).getElement(); 482 } 483 484 if ( !Hibernate.isInitialized(value) ) { 485 HibernateProxy proxy = (HibernateProxy) value; 486 LazyInitializer li = proxy.getHibernateLazyInitializer(); 487 reassociateProxy(li, proxy); 488 return true; 489 } 490 else { 491 return false; 492 } 493 } 494 495 499 public void reassociateProxy(Object value, Serializable id) throws MappingException { 500 if ( value instanceof ElementWrapper ) { 501 value = ( (ElementWrapper) value ).getElement(); 502 } 503 504 if ( value instanceof HibernateProxy ) { 505 if ( log.isDebugEnabled() ) log.debug("setting proxy identifier: " + id); 506 HibernateProxy proxy = (HibernateProxy) value; 507 LazyInitializer li = proxy.getHibernateLazyInitializer(); 508 li.setIdentifier(id); 509 reassociateProxy(li, proxy); 510 } 511 } 512 513 516 private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) throws HibernateException { 517 if ( li.getSession() != this ) { 518 EntityPersister persister = session.getFactory().getEntityPersister( li.getEntityName() ); 519 EntityKey key = new EntityKey( li.getIdentifier(), persister, session.getEntityMode() ); 520 if ( !proxiesByKey.containsKey(key) ) proxiesByKey.put(key, proxy); proxy.getHibernateLazyInitializer().setSession(session); 522 } 523 } 524 525 530 public Object unproxy(Object maybeProxy) throws HibernateException { 531 if ( maybeProxy instanceof ElementWrapper ) { 532 maybeProxy = ( (ElementWrapper) maybeProxy ).getElement(); 533 } 534 535 if ( maybeProxy instanceof HibernateProxy ) { 536 HibernateProxy proxy = (HibernateProxy) maybeProxy; 537 LazyInitializer li = proxy.getHibernateLazyInitializer(); 538 if ( li.isUninitialized() ) { 539 throw new PersistentObjectException( 540 "object was an uninitialized proxy for " + 541 li.getEntityName() 542 ); 543 } 544 return li.getImplementation(); } 546 else { 547 return maybeProxy; 548 } 549 } 550 551 558 public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException { 559 if ( maybeProxy instanceof ElementWrapper ) { 560 maybeProxy = ( (ElementWrapper) maybeProxy ).getElement(); 561 } 562 563 if ( maybeProxy instanceof HibernateProxy ) { 564 HibernateProxy proxy = (HibernateProxy) maybeProxy; 565 LazyInitializer li = proxy.getHibernateLazyInitializer(); 566 reassociateProxy(li, proxy); 567 return li.getImplementation(); } 569 else { 570 return maybeProxy; 571 } 572 } 573 574 581 public void checkUniqueness(EntityKey key, Object object) throws HibernateException { 582 Object entity = getEntity(key); 583 if ( entity == object ) { 584 throw new AssertionFailure( "object already associated, but no entry was found" ); 585 } 586 if ( entity != null ) { 587 throw new NonUniqueObjectException( key.getIdentifier(), key.getEntityName() ); 588 } 589 } 590 591 604 public Object narrowProxy(Object proxy, EntityPersister persister, EntityKey key, Object object) 605 throws HibernateException { 606 607 boolean alreadyNarrow = persister.getConcreteProxyClass( session.getEntityMode() ) 608 .isAssignableFrom( proxy.getClass() ); 609 610 if ( !alreadyNarrow ) { 611 612 if ( log.isWarnEnabled() ) 613 log.warn( 614 "Narrowing proxy to " + 615 persister.getConcreteProxyClass( session.getEntityMode() ) + 616 " - this operation breaks ==" 617 ); 618 619 if ( object != null ) { 620 proxiesByKey.remove(key); 621 return object; } 623 else { 624 proxy = persister.createProxy( key.getIdentifier(), session ); 625 proxiesByKey.put(key, proxy); return proxy; 627 } 628 629 } 630 else { 631 632 if ( object != null ) { 633 LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer(); 634 li.setImplementation(object); 635 } 636 637 return proxy; 638 639 } 640 641 } 642 643 648 public Object proxyFor(EntityPersister persister, EntityKey key, Object impl) 649 throws HibernateException { 650 if ( !persister.hasProxy() ) return impl; 651 Object proxy = proxiesByKey.get(key); 652 if ( proxy != null ) { 653 return narrowProxy(proxy, persister, key, impl); 654 } 655 else { 656 return impl; 657 } 658 } 659 660 665 public Object proxyFor(Object impl) throws HibernateException { 666 EntityEntry e = getEntry(impl); 667 EntityPersister p = e.getPersister(); 668 return proxyFor( p, new EntityKey( e.getId(), p, session.getEntityMode() ), impl ); 669 } 670 671 674 public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister) throws MappingException { 675 return getEntity( new EntityKey( key, collectionPersister.getOwnerEntityPersister(), session.getEntityMode() ) ); 676 } 677 678 681 public void addUninitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id) { 682 CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing); 683 addCollection(collection, ce, id); 684 } 685 686 689 public void addUninitializedDetachedCollection(CollectionPersister persister, PersistentCollection collection) { 690 CollectionEntry ce = new CollectionEntry( persister, collection.getKey() ); 691 addCollection( collection, ce, collection.getKey() ); 692 } 693 694 699 public void addNewCollection(CollectionPersister persister, PersistentCollection collection) 700 throws HibernateException { 701 addCollection(collection, persister); 702 } 703 704 707 private void addCollection(PersistentCollection coll, CollectionEntry entry, Serializable key) { 708 collectionEntries.put(coll, entry); 709 CollectionKey collectionKey = new CollectionKey( entry.getLoadedPersister(), key, session.getEntityMode() ); 710 PersistentCollection old = (PersistentCollection) collectionsByKey.put(collectionKey, coll); 711 if ( old != null ) { 712 if (old==coll) throw new AssertionFailure("bug adding collection twice"); 713 old.unsetSession(session); 715 collectionEntries.remove(old); 716 } 719 } 720 721 724 private void addCollection(PersistentCollection collection, CollectionPersister persister) 725 throws HibernateException { 726 CollectionEntry ce = new CollectionEntry(persister, collection); 727 collectionEntries.put(collection, ce); 728 } 729 730 734 public void addInitializedDetachedCollection(CollectionPersister collectionPersister, PersistentCollection collection) 735 throws HibernateException { 736 if ( collection.isUnreferenced() ) { 737 addCollection( collection, collectionPersister ); 739 } 740 else { 741 CollectionEntry ce = new CollectionEntry( collection, session.getFactory() ); 742 addCollection( collection, ce, collection.getKey() ); 743 } 744 } 745 746 749 public CollectionEntry addInitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id) 750 throws HibernateException { 751 CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing); 752 ce.postInitialize(collection); 753 addCollection(collection, ce, id); 754 return ce; 755 } 756 757 760 public PersistentCollection getCollection(CollectionKey collectionKey) { 761 return (PersistentCollection) collectionsByKey.get(collectionKey); 762 } 763 764 768 public void addNonLazyCollection(PersistentCollection collection) { 769 nonlazyCollections.add(collection); 770 } 771 772 777 public void initializeNonLazyCollections() throws HibernateException { 778 if ( loadCounter == 0 ) { 779 log.debug( "initializing non-lazy collections" ); 780 loadCounter++; try { 783 int size; 784 while ( ( size = nonlazyCollections.size() ) > 0 ) { 785 ( (PersistentCollection) nonlazyCollections.remove( size - 1 ) ).forceInitialization(); 787 } 788 } 789 finally { 790 loadCounter--; 791 clearNullProperties(); 792 } 793 } 794 } 795 796 797 800 public PersistentCollection getCollectionHolder(Object array) { 801 return (PersistentCollection) arrayHolders.get(array); 802 } 803 804 809 public void addCollectionHolder(PersistentCollection holder) { 810 arrayHolders.put( holder.getValue(), holder ); 812 } 813 814 public PersistentCollection removeCollectionHolder(Object array) { 815 return (PersistentCollection) arrayHolders.remove(array); 816 } 817 818 821 public Serializable getSnapshot(PersistentCollection coll) { 822 return getCollectionEntry(coll).getSnapshot(); 823 } 824 825 828 public boolean isInverseCollection(PersistentCollection collection) { 829 CollectionEntry ce = getCollectionEntry(collection); 830 return ce != null && ce.getLoadedPersister().isInverse(); 831 } 832 833 838 public CollectionEntry getCollectionEntryOrNull(Object collection) { 839 PersistentCollection coll; 840 if ( collection instanceof PersistentCollection ) { 841 coll = (PersistentCollection) collection; 842 } 844 else { 845 coll = getCollectionHolder(collection); 846 if ( coll == null ) { 847 Iterator wrappers = IdentityMap.keyIterator(collectionEntries); 850 while ( wrappers.hasNext() ) { 851 PersistentCollection pc = (PersistentCollection) wrappers.next(); 852 if ( pc.isWrapper(collection) ) { 853 coll = pc; 854 break; 855 } 856 } 857 } 858 } 859 860 return (coll == null) ? null : getCollectionEntry(coll); 861 } 862 863 866 public Object getProxy(EntityKey key) { 867 return proxiesByKey.get(key); 868 } 869 870 873 public void addProxy(EntityKey key, Object proxy) { 874 proxiesByKey.put(key, proxy); 875 } 876 877 880 public Object removeProxy(EntityKey key) { 881 return proxiesByKey.remove(key); 882 } 883 884 889 892 893 898 901 902 905 906 909 public HashSet getNullifiableEntityKeys() { 910 return nullifiableEntityKeys; 911 } 912 913 public Map getEntitiesByKey() { 914 return entitiesByKey; 915 } 916 917 public Map getEntityEntries() { 918 return entityEntries; 919 } 920 921 public Map getCollectionEntries() { 922 return collectionEntries; 923 } 924 925 public Map getCollectionsByKey() { 926 return collectionsByKey; 927 } 928 929 933 936 937 941 944 945 public int getCascadeLevel() { 946 return cascading; 947 } 948 949 public int incrementCascadeLevel() { 950 return ++cascading; 951 } 952 953 public int decrementCascadeLevel() { 954 return --cascading; 955 } 956 957 public boolean isFlushing() { 958 return flushing; 959 } 960 961 public void setFlushing(boolean flushing) { 962 this.flushing = flushing; 963 } 964 965 968 public void beforeLoad() { 969 loadCounter++; 970 } 971 972 975 public void afterLoad() { 976 loadCounter--; 977 } 978 979 984 public String toString() { 985 return new StringBuffer () 986 .append("PersistenceContext[entityKeys=") 987 .append(entitiesByKey.keySet()) 988 .append(",collectionKeys=") 989 .append(collectionsByKey.keySet()) 990 .append("]") 991 .toString(); 992 } 993 994 999 public Serializable getOwnerId(String entity, String property, Object childEntity, Map mergeMap) { 1000 1001 EntityPersister persister = session.getFactory() 1002 .getEntityPersister(entity); 1003 final CollectionPersister collectionPersister = session.getFactory() 1004 .getCollectionPersister(entity + '.' + property); 1005 1006 Iterator entities = entityEntries.entrySet().iterator(); 1007 while ( entities.hasNext() ) { 1008 Map.Entry me = (Map.Entry ) entities.next(); 1009 EntityEntry ee = (EntityEntry) me.getValue(); 1010 if ( persister.isSubclassEntityName( ee.getEntityName() ) ) { 1011 Object instance = me.getKey(); 1012 1013 boolean found = isFoundInParent( 1015 property, 1016 childEntity, 1017 persister, 1018 collectionPersister, 1019 instance 1020 ); 1021 1022 if (!found && mergeMap!=null) { 1023 Object unmergedInstance = mergeMap.get(instance); 1025 Object unmergedChild = mergeMap.get(childEntity); 1026 if ( unmergedInstance!=null && unmergedChild!=null ) { 1027 found = isFoundInParent( 1028 property, 1029 unmergedChild, 1030 persister, 1031 collectionPersister, 1032 unmergedInstance 1033 ); 1034 } 1035 } 1036 1037 if ( found ) { 1038 return ee.getId(); 1039 } 1040 1041 } 1042 } 1043 return null; 1044 } 1045 1046 private boolean isFoundInParent( 1047 String property, 1048 Object childEntity, 1049 EntityPersister persister, 1050 CollectionPersister collectionPersister, 1051 Object potentialParent 1052 ) { 1053 Object collection = persister.getPropertyValue( 1054 potentialParent, 1055 property, 1056 session.getEntityMode() 1057 ); 1058 return collection!=null && Hibernate.isInitialized(collection) && 1059 collectionPersister.getCollectionType() 1060 .contains(collection, childEntity, collectionPersister, session); 1061 } 1062 1063 1067 public Object getIndexInOwner(String entity, String property, Object childEntity, Map mergeMap) { 1068 1069 EntityPersister persister = session.getFactory() 1070 .getEntityPersister(entity); 1071 CollectionPersister cp = session.getFactory() 1072 .getCollectionPersister(entity + '.' + property); 1073 Iterator entities = entityEntries.entrySet().iterator(); 1074 while ( entities.hasNext() ) { 1075 Map.Entry me = (Map.Entry ) entities.next(); 1076 EntityEntry ee = (EntityEntry) me.getValue(); 1077 if ( persister.isSubclassEntityName( ee.getEntityName() ) ) { 1078 Object instance = me.getKey(); 1079 1080 Object index = getIndexInParent(property, childEntity, persister, cp, instance); 1081 1082 if (index==null && mergeMap!=null) { 1083 Object unmergedInstance = mergeMap.get(instance); 1084 Object unmergedChild = mergeMap.get(childEntity); 1085 if ( unmergedInstance!=null && unmergedChild!=null ) { 1086 index = getIndexInParent(property, unmergedChild, persister, cp, unmergedInstance); 1087 } 1088 } 1089 1090 if (index!=null) return index; 1091 } 1092 } 1093 return null; 1094 } 1095 1096 private Object getIndexInParent( 1097 String property, 1098 Object childEntity, 1099 EntityPersister persister, 1100 CollectionPersister collectionPersister, 1101 Object potentialParent 1102 ){ 1103 Object collection = persister.getPropertyValue( potentialParent, property, session.getEntityMode() ); 1104 if ( collection!=null && Hibernate.isInitialized(collection) ) { 1105 return collectionPersister.getCollectionType().indexOf(collection, childEntity); 1106 } 1107 else { 1108 return null; 1109 } 1110 } 1111 1112 1116 public void addNullProperty(EntityKey ownerKey, String propertyName) { 1117 nullAssociations.add( new AssociationKey(ownerKey, propertyName) ); 1118 } 1119 1120 1123 public boolean isPropertyNull(EntityKey ownerKey, String propertyName) { 1124 return nullAssociations.contains( new AssociationKey(ownerKey, propertyName) ); 1125 } 1126 1127 private void clearNullProperties() { 1128 nullAssociations.clear(); 1129 } 1130 1131 public void setReadOnly(Object entity, boolean readOnly) { 1132 EntityEntry entry = getEntry(entity); 1133 if (entry==null) { 1134 throw new TransientObjectException("Instance was not associated with the session"); 1135 } 1136 entry.setReadOnly(readOnly, entity); 1137 hasNonReadOnlyEntities = hasNonReadOnlyEntities || !readOnly; 1138 } 1139} 1140 | Popular Tags |