2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.common
;
12 import java
.lang
.reflect
.Field
;
13 import java
.lang
.reflect
.InvocationTargetException
;
14 import java
.lang
.reflect
.Method
;
15 import java
.lang
.reflect
.Modifier
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Collection
;
18 import java
.util
.HashMap
;
19 import java
.util
.HashSet
;
20 import java
.util
.List
;
24 import javax
.naming
.Reference
;
26 import org
.apache
.commons
.lang
.StringUtils
;
27 import org
.apache
.commons
.lang
.UnhandledException
;
28 import org
.apache
.log4j
.Logger
;
29 import org
.hibernate
.Criteria
;
30 import org
.hibernate
.HibernateException
;
31 import org
.hibernate
.MappingException
;
32 import org
.hibernate
.Query
;
33 import org
.hibernate
.Session
;
34 import org
.hibernate
.SessionFactory
;
35 import org
.hibernate
.collection
.internal
.AbstractPersistentCollection
;
36 import org
.hibernate
.collection
.spi
.PersistentCollection
;
37 import org
.hibernate
.criterion
.CriteriaSpecification
;
38 import org
.hibernate
.criterion
.Criterion
;
39 import org
.hibernate
.criterion
.Restrictions
;
40 import org
.hibernate
.engine
.spi
.CollectionEntry
;
41 import org
.hibernate
.engine
.spi
.SessionFactoryImplementor
;
42 import org
.hibernate
.engine
.spi
.SessionImplementor
;
43 import org
.hibernate
.internal
.SessionFactoryImpl
;
44 import org
.hibernate
.internal
.SessionImpl
;
45 import org
.hibernate
.metadata
.ClassMetadata
;
46 import org
.hibernate
.metadata
.CollectionMetadata
;
47 import org
.hibernate
.persister
.collection
.CollectionPersister
;
48 import org
.hibernate
.persister
.collection
.OneToManyPersister
;
49 import org
.hibernate
.persister
.entity
.AbstractEntityPersister
;
50 import org
.hibernate
.stat
.Statistics
;
51 import org
.hibernate
.type
.AnyType
;
52 import org
.hibernate
.type
.BooleanType
;
53 import org
.hibernate
.type
.CollectionType
;
54 import org
.hibernate
.type
.ComponentType
;
55 import org
.hibernate
.type
.DoubleType
;
56 import org
.hibernate
.type
.EntityType
;
57 import org
.hibernate
.type
.EnumType
;
58 import org
.hibernate
.type
.FloatType
;
59 import org
.hibernate
.type
.IntegerType
;
60 import org
.hibernate
.type
.LongType
;
61 import org
.hibernate
.type
.MaterializedClobType
;
62 import org
.hibernate
.type
.SerializableType
;
63 import org
.hibernate
.type
.SetType
;
64 import org
.hibernate
.type
.StringType
;
65 import org
.hibernate
.type
.Type
;
66 import org
.jadira
.usertype
.dateandtime
.joda
.PersistentDateTime
;
67 import org
.springframework
.dao
.DataAccessException
;
68 import org
.springframework
.stereotype
.Repository
;
70 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
71 import eu
.etaxonomy
.cdm
.common
.DoubleResult
;
72 import eu
.etaxonomy
.cdm
.hibernate
.DOIUserType
;
73 import eu
.etaxonomy
.cdm
.hibernate
.EnumUserType
;
74 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
75 import eu
.etaxonomy
.cdm
.hibernate
.PartialUserType
;
76 import eu
.etaxonomy
.cdm
.hibernate
.URIUserType
;
77 import eu
.etaxonomy
.cdm
.hibernate
.UUIDUserType
;
78 import eu
.etaxonomy
.cdm
.hibernate
.WSDLDefinitionUserType
;
79 import eu
.etaxonomy
.cdm
.model
.common
.AnnotatableEntity
;
80 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
81 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
82 import eu
.etaxonomy
.cdm
.model
.common
.Extension
;
83 import eu
.etaxonomy
.cdm
.model
.common
.ICdmBase
;
84 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
85 import eu
.etaxonomy
.cdm
.model
.common
.Marker
;
86 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaData
;
87 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
88 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
89 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
90 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.ICdmGenericDao
;
91 import eu
.etaxonomy
.cdm
.strategy
.match
.CacheMatcher
;
92 import eu
.etaxonomy
.cdm
.strategy
.match
.DefaultMatchStrategy
;
93 import eu
.etaxonomy
.cdm
.strategy
.match
.FieldMatcher
;
94 import eu
.etaxonomy
.cdm
.strategy
.match
.IMatchStrategy
;
95 import eu
.etaxonomy
.cdm
.strategy
.match
.IMatchable
;
96 import eu
.etaxonomy
.cdm
.strategy
.match
.MatchException
;
97 import eu
.etaxonomy
.cdm
.strategy
.match
.MatchMode
;
98 import eu
.etaxonomy
.cdm
.strategy
.match
.Matching
;
99 import eu
.etaxonomy
.cdm
.strategy
.merge
.DefaultMergeStrategy
;
100 import eu
.etaxonomy
.cdm
.strategy
.merge
.IMergable
;
101 import eu
.etaxonomy
.cdm
.strategy
.merge
.IMergeStrategy
;
102 import eu
.etaxonomy
.cdm
.strategy
.merge
.MergeException
;
105 public class CdmGenericDaoImpl
extends CdmEntityDaoBase
<CdmBase
> implements ICdmGenericDao
{
106 private static final Logger logger
= Logger
.getLogger(CdmGenericDaoImpl
.class);
109 private Set
<Class
<?
extends CdmBase
>> allCdmClasses
= null;
110 private Map
<Class
<?
extends CdmBase
>, Set
<ReferenceHolder
>> referenceMap
= new HashMap
<Class
<?
extends CdmBase
>, Set
<ReferenceHolder
>>();
112 private class ReferenceHolder
{
114 Class
<?
extends CdmBase
> otherClass
;
115 Class
<?
extends CdmBase
> itemClass
;
116 public boolean isCollection(){return itemClass
!= null;};
117 public String
toString(){return otherClass
.getSimpleName() + "." + propertyName
;};
121 public CdmGenericDaoImpl() {
122 super(CdmBase
.class);
126 public List
<CdmBase
> getCdmBasesByFieldAndClass(Class clazz
, String propertyName
, CdmBase referencedCdmBase
){
127 Session session
= super.getSession();
129 Criteria criteria
= session
.createCriteria(clazz
);
130 criteria
.add(Restrictions
.eq(propertyName
, referencedCdmBase
));
131 return criteria
.list();
135 public List
<CdmBase
> getCdmBasesWithItemInCollection(Class itemClass
, Class clazz
, String propertyName
, CdmBase item
){
136 Session session
= super.getSession();
137 String thisClassStr
= itemClass
.getSimpleName();
138 String otherClassStr
= clazz
.getSimpleName();
139 String queryStr
= " SELECT other FROM "+ thisClassStr
+ " this, " + otherClassStr
+ " other " +
140 " WHERE this = :referencedObject AND this member of other."+propertyName
;
141 Query query
= session
.createQuery(queryStr
).setEntity("referencedObject", item
);
142 List
<CdmBase
> result
= query
.list();
147 public Set
<Class
<?
extends CdmBase
>> getAllCdmClasses(boolean includeAbstractClasses
){
148 Set
<Class
<?
extends CdmBase
>> result
= new HashSet
<Class
<?
extends CdmBase
>>();
150 SessionFactory sessionFactory
= getSession().getSessionFactory();
151 Map
<?
,?
> allClassMetadata
= sessionFactory
.getAllClassMetadata();
152 Collection
<?
> keys
= allClassMetadata
.keySet();
153 for (Object oKey
: keys
){
154 if (oKey
instanceof String
){
155 String strKey
= (String
)oKey
;
156 if (! strKey
.endsWith("_AUD")){
158 Class clazz
= Class
.forName(strKey
);
159 boolean isAbstractClass
= Modifier
.isAbstract(clazz
.getModifiers());
160 if (! isAbstractClass
|| includeAbstractClasses
){
163 } catch (ClassNotFoundException e
) {
164 logger
.warn("Class not found: " + strKey
);
168 logger
.warn("key is not of type String: " + oKey
);
175 public Set
<CdmBase
> getReferencingObjects(CdmBase referencedCdmBase
){
176 Set
<CdmBase
> result
= new HashSet
<CdmBase
>();
178 referencedCdmBase
= (CdmBase
)HibernateProxyHelper
.deproxy(referencedCdmBase
);
179 Class
<?
extends CdmBase
> referencedClass
= referencedCdmBase
.getClass();
181 Set
<ReferenceHolder
> holderSet
= referenceMap
.get(referencedClass
);
182 if (holderSet
== null){
183 holderSet
= makeHolderSet(referencedClass
);
184 referenceMap
.put(referencedClass
, holderSet
);
186 for (ReferenceHolder refHolder
: holderSet
){
187 handleReferenceHolder(referencedCdmBase
, result
, refHolder
);
190 } catch (Exception e
) {
192 throw new RuntimeException(e
);
197 public Set
<CdmBase
> getReferencingObjectsForDeletion(CdmBase referencedCdmBase
){
198 Set
<CdmBase
> result
= getReferencingObjects(referencedCdmBase
);
199 Set
<ReferenceHolder
> holderSet
= referenceMap
.get(IdentifiableEntity
.class);
201 if (holderSet
== null){
202 holderSet
= makeHolderSet(IdentifiableEntity
.class);
203 referenceMap
.put(IdentifiableEntity
.class, holderSet
);
205 Set
<CdmBase
> resultIdentifiableEntity
= new HashSet
<CdmBase
>();
206 for (ReferenceHolder refHolder
: holderSet
){
207 handleReferenceHolder(referencedCdmBase
, resultIdentifiableEntity
, refHolder
);
209 result
.removeAll(resultIdentifiableEntity
);
212 } catch (Exception e
) {
214 throw new RuntimeException(e
);
220 * @param referencedCdmBase
224 private void handleReferenceHolder(CdmBase referencedCdmBase
,
225 Set
<CdmBase
> result
, ReferenceHolder refHolder
) {
226 boolean isCollection
= refHolder
.isCollection();
228 result
.addAll(getCdmBasesWithItemInCollection(refHolder
.itemClass
, refHolder
.otherClass
, refHolder
.propertyName
, referencedCdmBase
));
230 result
.addAll(getCdmBasesByFieldAndClass(refHolder
.otherClass
, refHolder
.propertyName
, referencedCdmBase
));
236 * @param referencedClass
238 * @throws NoSuchFieldException
239 * @throws ClassNotFoundException
241 private Set
<ReferenceHolder
> makeHolderSet(Class
<?
> referencedClass
) throws ClassNotFoundException
, NoSuchFieldException
{
242 Set
<ReferenceHolder
> result
= new HashSet
<ReferenceHolder
>();
245 if (allCdmClasses
== null){
246 allCdmClasses
= getAllCdmClasses(false); //findAllCdmClasses();
248 //referencedCdmBase = (CdmBase)HibernateProxyHelper.deproxy(referencedCdmBase);
249 SessionFactory sessionFactory
= getSession().getSessionFactory();
252 for (Class
<?
extends CdmBase
> cdmClass
: allCdmClasses
){
253 ClassMetadata classMetadata
= sessionFactory
.getClassMetadata(cdmClass
);
254 Type
[] propertyTypes
= classMetadata
.getPropertyTypes();
256 for (Type propertyType
: propertyTypes
){
257 String propertyName
= classMetadata
.getPropertyNames()[propertyNr
];
258 makePropertyType(result
, referencedClass
, sessionFactory
, cdmClass
, propertyType
, propertyName
, false);
267 * @param referencedCdmBase
269 * @param referencedClass
270 * @param sessionFactory
272 * @param propertyType
273 * @param propertyName
274 * @throws ClassNotFoundException
275 * @throws NoSuchFieldException
277 private void makePropertyType(
278 // CdmBase referencedCdmBase,
279 Set
<ReferenceHolder
> result
,
280 Class
<?
> referencedClass
,
281 SessionFactory sessionFactory
, Class
<?
extends CdmBase
> cdmClass
,
282 Type propertyType
, String propertyName
, boolean isCollection
)
283 throws ClassNotFoundException
, NoSuchFieldException
{
286 if (propertyType
.isEntityType()){
287 EntityType entityType
= (EntityType
)propertyType
;
288 String associatedEntityName
= entityType
.getAssociatedEntityName();
289 Class
<?
> entityClass
= Class
.forName(associatedEntityName
);
290 if (entityClass
.isInterface()){
291 logger
.debug("There is an interface");
293 if (entityClass
.isAssignableFrom(referencedClass
)){
294 makeSingleProperty(referencedClass
, entityClass
, propertyName
, cdmClass
, result
, isCollection
);
296 }else if (propertyType
.isCollectionType()){
297 CollectionType collectionType
= (CollectionType
)propertyType
;
298 //String role = collectionType.getRole();
299 Type elType
= collectionType
.getElementType((SessionFactoryImplementor
)sessionFactory
);
300 makePropertyType(result
, referencedClass
, sessionFactory
, cdmClass
, elType
, propertyName
, true);
301 }else if (propertyType
.isAnyType()){
302 // AnyType anyType = (AnyType)propertyType;
303 Field field
= cdmClass
.getDeclaredField(propertyName
);
304 Class
<?
> returnType
= field
.getType();
305 if (returnType
.isInterface()){
306 logger
.debug("There is an interface");
308 if (returnType
.isAssignableFrom(referencedClass
)){
309 makeSingleProperty(referencedClass
, returnType
, propertyName
, cdmClass
, result
, isCollection
);
311 }else if (propertyType
.isComponentType()){
312 ComponentType componentType
= (ComponentType
)propertyType
;
313 Type
[] subTypes
= componentType
.getSubtypes();
314 // Field field = cdmClass.getDeclaredField(propertyName);
315 // Class returnType = field.getType();
317 for (Type subType
: subTypes
){
318 String subPropertyName
= componentType
.getPropertyNames()[propertyNr
];
319 if (!isNoDoType(subType
)){
320 logger
.warn("SubType not yet handled: " + subType
);
322 // handlePropertyType(referencedCdmBase, result, referencedClass,
323 // sessionFactory, cdmClass, subType, subPropertyName, isCollection);
326 }else if (isNoDoType(propertyType
)){
329 logger
.warn("propertyType not yet handled: " + propertyType
.getName());
332 // if (! type.isInterface()){
333 // if (referencedClass.isAssignableFrom(type)||
334 // type.isAssignableFrom(referencedClass) && CdmBase.class.isAssignableFrom(type)){
335 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
338 // }else if (type.isAssignableFrom(referencedClass)){
339 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
343 private boolean makeSingleProperty(Class itemClass
, Class
<?
> type
, String propertyName
, Class cdmClass
, Set
<ReferenceHolder
> result
,/*CdmBase item,*/ boolean isCollection
){
344 String fieldName
= StringUtils
.rightPad(propertyName
, 30);
345 String className
= StringUtils
.rightPad(cdmClass
.getSimpleName(), 30);
346 String returnTypeName
= StringUtils
.rightPad(type
.getSimpleName(), 30);
348 // logger.debug(fieldName + "\t\t" + className + "\t\t" + returnTypeName);
349 ReferenceHolder refHolder
= new ReferenceHolder();
350 refHolder
.propertyName
= propertyName
;
351 refHolder
.otherClass
= cdmClass
;
352 refHolder
.itemClass
= (isCollection ? itemClass
: null) ;
353 result
.add(refHolder
);
358 * @param propertyType
361 private boolean isNoDoType(Type propertyType
) {
362 boolean result
= false;
363 Class
<?
>[] classes
= new Class
[]{
364 PersistentDateTime
.class,
365 WSDLDefinitionUserType
.class,
367 PartialUserType
.class,
371 MaterializedClobType
.class,
374 SerializableType
.class,
381 Set
<String
> classNames
= new HashSet
<String
>();
382 for (Class
<?
> clazz
: classes
){
383 classNames
.add(clazz
.getCanonicalName());
384 if (clazz
== propertyType
.getClass()){
388 String propertyTypeClassName
= propertyType
.getName();
389 if (classNames
.contains(propertyTypeClassName
)){
396 public List
<CdmBase
> getHqlResult(String hqlQuery
){
397 Query query
= getSession().createQuery(hqlQuery
);
398 List
<CdmBase
> result
= query
.list();
403 public Query
getHqlQuery(String hqlQuery
){
404 Query query
= getSession().createQuery(hqlQuery
);
409 public <T
extends CdmBase
> void merge(T cdmBase1
, T cdmBase2
, IMergeStrategy mergeStrategy
) throws MergeException
{
410 Class
<T
> clazz
= (Class
<T
>)cdmBase1
.getClass();
411 SessionImpl session
= (SessionImpl
) getSession();
412 SessionFactory sessionFactory
= session
.getSessionFactory();
413 if (mergeStrategy
== null){
414 mergeStrategy
= DefaultMergeStrategy
.NewInstance(cdmBase1
.getClass());
417 //test null and types
418 testMergeValid(cdmBase1
, cdmBase2
);
424 Set
<ICdmBase
> deleteSet
= new HashSet
<ICdmBase
>();
425 Set
<ICdmBase
> cloneSet
= new HashSet
<ICdmBase
>();
426 if (cdmBase1
instanceof IMergable
){
427 IMergable mergable1
= (IMergable
)cdmBase1
;
428 IMergable mergable2
= (IMergable
)cdmBase2
;
429 deleteSet
= mergeStrategy
.invoke(mergable1
, mergable2
, cloneSet
);
430 //session.saveOrUpdate(mergable1);
433 //((IMergable)cdmBase1).mergeInto(cdmBase2, DefaultMergeStrategy.NewInstance(cdmBase1.getClass()));
435 mergeExternal(cdmBase1
, cdmBase2
, clazz
, session
);
439 if (cdmBase2
.getId() > 0){
440 session
.saveOrUpdate(cdmBase2
);
441 //rearrange references to cdmBase2
442 reallocateReferences(cdmBase1
, cdmBase2
, sessionFactory
, clazz
, cloneSet
);
445 //remove deleted objects
447 //session.delete(null, mergable2, true, null);
448 session
.delete(cdmBase2
);
449 for (ICdmBase toBeDeleted
: deleteSet
){
450 logger
.debug("Delete " + toBeDeleted
);
451 if (toBeDeleted
!= cdmBase2
){
452 session
.delete(toBeDeleted
);
460 } catch (Exception e
) {
461 throw new MergeException(e
);
471 * @param sessionFactory
472 * @throws MergeException
473 * @throws ClassNotFoundException
474 * @throws NoSuchFieldException
476 private <T
extends CdmBase
> void mergeExternal(T cdmBase1
, T cdmBase2
, Class
<T
> clazz
,
477 Session session
) throws MergeException
{
479 logger
.warn("Merge external");
480 handleAnnotationsEtc(cdmBase1
, cdmBase2
, session
);
482 SessionFactoryImpl sessionFactory
= (SessionFactoryImpl
) session
.getSessionFactory();
484 Map
<String
, ClassMetadata
> allClassMetadata
= sessionFactory
.getAllClassMetadata();
487 getCollectionRoles(clazz
, sessionFactory
);
489 TaxonNameBase name1
= BotanicalName
.NewInstance(null);
490 name1
.getTaxonBases();
492 Type propType
= sessionFactory
.getReferencedPropertyType(BotanicalName
.class.getCanonicalName(), "taxonBases");
493 Map collMetadata
= sessionFactory
.getAllCollectionMetadata();
494 //roles = sessionFactory.getCollectionRolesByEntityParticipant("eu.etaxonomy.cdm.model.name.BotanicalName");
495 CollectionPersister collPersister
;
497 collPersister
= sessionFactory
.getCollectionPersister(TaxonNameBase
.class.getCanonicalName()+".annotations");
498 } catch (MappingException e
) {
499 // TODO Auto-generated catch block
502 // Statistics statistics = sessionFactory.getStatistics();
504 ClassMetadata taxonMetaData
= sessionFactory
.getClassMetadata(Taxon
.class);
505 String ename
= taxonMetaData
.getEntityName();
507 Reference ref
= sessionFactory
.getReference();
509 } catch (Exception e
) {
510 // TODO Auto-generated catch block
515 ClassMetadata classMetadata
= getSession().getSessionFactory().getClassMetadata(clazz
);
516 Type
[] propertyTypes
= classMetadata
.getPropertyTypes();
518 for (Type propertyType
: propertyTypes
){
519 String propertyName
= classMetadata
.getPropertyNames()[propertyNr
];
520 logger
.debug(propertyName
);
521 makeMergeProperty(cdmBase1
, cdmBase2
, propertyType
, propertyName
, sessionFactory
, false);
524 Set
<String
> collectionRoles
;
525 if (classMetadata
instanceof AbstractEntityPersister
){
526 AbstractEntityPersister persister
= (AbstractEntityPersister
)classMetadata
;
527 String rootName
= persister
.getRootEntityName();
528 collectionRoles
= sessionFactory
.getCollectionRolesByEntityParticipant(rootName
);
529 for (String collectionRole
: collectionRoles
){
530 CollectionMetadata collMetadata2
= sessionFactory
.getCollectionMetadata(collectionRole
);
531 String role
= collMetadata2
.getRole();
532 Type elType
= collMetadata2
.getElementType();
541 * @param sessionFactory
543 private <T
> Set
<String
> getCollectionRoles(Class
<T
> clazz
,
544 SessionFactoryImpl sessionFactory
) {
545 Set
<String
> collectionRoles
= null;
546 ClassMetadata classMetaData
= sessionFactory
.getClassMetadata(clazz
);
547 if (classMetaData
instanceof AbstractEntityPersister
){
548 AbstractEntityPersister persister
= (AbstractEntityPersister
)classMetaData
;
549 String rootName
= persister
.getRootEntityName();
550 collectionRoles
= sessionFactory
.getCollectionRolesByEntityParticipant(rootName
);
551 for (String collectionRole
: collectionRoles
){
552 CollectionMetadata collMetadata
= sessionFactory
.getCollectionMetadata(collectionRole
);
553 CollectionPersister collPersister
= sessionFactory
.getCollectionPersister(collectionRole
);
557 logger
.warn("Class metadata is not of type AbstractEntityPersister");
558 throw new UnhandledException("Class metadata is not of type AbstractEntityPersister", null);
560 return collectionRoles
;
564 private <T
extends CdmBase
> void makeMergeProperty(T cdmBase1
, T cdmBase2
, Type propertyType
, String propertyName
, SessionFactoryImpl sessionFactory
, boolean isCollection
) throws MergeException
568 Class
<T
> clazz
= (Class
<T
>)cdmBase1
.getClass();
569 if (isNoDoType(propertyType
)){
571 }else if (propertyType
.isEntityType()){
572 //Field field = clazz.getField(propertyName);
573 EntityType entityType
= (EntityType
)propertyType
;
574 String associatedEntityName
= entityType
.getAssociatedEntityName();
575 Class entityClass
= Class
.forName(associatedEntityName
);
576 // Type refPropType = sessionFactory.getReferencedPropertyType(entityClass.getCanonicalName(), propertyName);
577 Set
<String
> collectionRoles
= getCollectionRoles(clazz
, sessionFactory
);
578 for (String collectionRole
: collectionRoles
){
579 CollectionMetadata collMetadata
= sessionFactory
.getCollectionMetadata(collectionRole
);
580 String role
= collMetadata
.getRole();
585 // if (entityClass.isInterface()){
586 // logger.debug("So ein interface");
588 // if (entityClass.isAssignableFrom(clazz)){
589 // makeSingleProperty(referencedClass, entityClass, propertyName, cdmClass, result, isCollection);
591 }else if (propertyType
.isCollectionType()){
592 CollectionType collectionType
= (CollectionType
)propertyType
;
593 String role
= collectionType
.getRole();
594 Type elType
= collectionType
.getElementType((SessionFactoryImplementor
)sessionFactory
);
595 String n
= collectionType
.getAssociatedEntityName(sessionFactory
);
596 CollectionMetadata collMetadata
= sessionFactory
.getCollectionMetadata(role
);
597 if (collMetadata
instanceof OneToManyPersister
){
598 OneToManyPersister oneManyPersister
= (OneToManyPersister
)collMetadata
;
599 String className
= oneManyPersister
.getOwnerEntityName();
600 Class
<?
> myClass
= Class
.forName(className
);
601 Field field
= myClass
.getDeclaredField(propertyName
);
602 field
.setAccessible(true);
604 if (collectionType
instanceof SetType
){
605 Set set2
= (Set
)field
.get(cdmBase2
);
606 Set
<Object
> set1
= (Set
<Object
>)field
.get(cdmBase1
);
607 for (Object obj2
: set2
){
611 } catch (IllegalArgumentException e
) {
612 // TODO Auto-generated catch block
614 } catch (IllegalAccessException e
) {
615 // TODO Auto-generated catch block
622 // makePropertyType(result, referencedClass, sessionFactory, cdmClass, elType, propertyName, true);
623 }else if (propertyType
.isAnyType()){
624 AnyType anyType
= (AnyType
)propertyType
;
625 Field field
= clazz
.getDeclaredField(propertyName
);
626 Class returnType
= field
.getType();
627 // if (returnType.isInterface()){
628 // logger.debug("So ein interface");
630 // if (returnType.isAssignableFrom(referencedClass)){
631 // makeSingleProperty(referencedClass, returnType, propertyName, cdmClass, result, isCollection);
633 }else if (propertyType
.isComponentType()){
634 ComponentType componentType
= (ComponentType
)propertyType
;
635 Type
[] subTypes
= componentType
.getSubtypes();
636 // Field field = cdmClass.getDeclaredField(propertyName);
637 // Class returnType = field.getType();
639 for (Type subType
: subTypes
){
640 String subPropertyName
= componentType
.getPropertyNames()[propertyNr
];
641 if (!isNoDoType(subType
)){
642 logger
.warn("SubType not yet handled: " + subType
);
644 // handlePropertyType(referencedCdmBase, result, referencedClass,
645 // sessionFactory, cdmClass, subType, subPropertyName, isCollection);
649 logger
.warn("propertyType not yet handled: " + propertyType
.getName());
652 // if (! type.isInterface()){
653 // if (referencedClass.isAssignableFrom(type)||
654 // type.isAssignableFrom(referencedClass) && CdmBase.class.isAssignableFrom(type)){
655 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
658 // }else if (type.isAssignableFrom(referencedClass)){
659 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
660 } catch (Exception e
) {
661 throw new MergeException(e
);
668 private void reallocateReferences(CdmBase cdmBase1
, CdmBase cdmBase2
, SessionFactory sessionFactory
, Class clazz
, Set
<ICdmBase
> cloneSet
){
670 Set
<ReferenceHolder
> holderSet
= referenceMap
.get(clazz
);
671 if (holderSet
== null){
672 holderSet
= makeHolderSet(clazz
);
673 referenceMap
.put(clazz
, holderSet
);
675 for (ReferenceHolder refHolder
: holderSet
){
676 reallocateByHolder(cdmBase1
, cdmBase2
, refHolder
, cloneSet
);
679 } catch (Exception e
) {
681 throw new RuntimeException(e
);
689 * @throws MergeException
691 private void reallocateByHolder(CdmBase cdmBase1
, CdmBase cdmBase2
, ReferenceHolder refHolder
, Set
<ICdmBase
> cloneSet
) throws MergeException
{
693 if (refHolder
.isCollection()){
694 reallocateCollection(cdmBase1
, cdmBase2
, refHolder
, cloneSet
);
696 reallocateSingleItem(cdmBase1
, cdmBase2
, refHolder
, cloneSet
);
698 } catch (Exception e
) {
699 throw new MergeException("Error during reallocation of references to merge object: " + cdmBase2
, e
);
709 * @throws MergeException
710 * @throws NoSuchFieldException
711 * @throws SecurityException
712 * @throws IllegalAccessException
713 * @throws IllegalArgumentException
714 * @throws InvocationTargetException
716 private void reallocateCollection(CdmBase cdmBase1
, CdmBase cdmBase2
,
717 ReferenceHolder refHolder
, Set
<ICdmBase
> cloneSet
) throws MergeException
, SecurityException
, NoSuchFieldException
, IllegalArgumentException
, IllegalAccessException
, InvocationTargetException
{
718 List
<CdmBase
> list
= getCdmBasesWithItemInCollection(refHolder
.itemClass
, refHolder
.otherClass
, refHolder
.propertyName
, cdmBase2
);
719 for (CdmBase referencingObject
: list
){
720 Field referencingField
= getFieldRecursive(refHolder
.otherClass
, refHolder
.propertyName
);
721 referencingField
.setAccessible(true);
722 Object collection
= referencingField
.get(referencingObject
);
723 if (! (collection
instanceof Collection
)){
724 throw new MergeException ("Reallocation of collections for collection other than set and list not yet implemented");
726 Method addMethod
= DefaultMergeStrategy
.getAddMethod(referencingField
, false);
727 Method removeMethod
= DefaultMergeStrategy
.getAddMethod(referencingField
, true);
728 addMethod
.invoke(referencingObject
, cdmBase1
);
729 removeMethod
.invoke(referencingObject
, cdmBase2
);
733 private Field
getFieldRecursive(Class clazz
, String propertyName
) throws NoSuchFieldException
{
735 return clazz
.getDeclaredField(propertyName
);
736 } catch (NoSuchFieldException e
) {
737 Class superClass
= clazz
.getSuperclass();
738 if (CdmBase
.class.isAssignableFrom(superClass
)){
739 return getFieldRecursive(superClass
, propertyName
);
747 * @throws NoSuchFieldException
748 * @throws SecurityException
749 * @throws IllegalAccessException
750 * @throws IllegalArgumentException
753 private void reallocateSingleItem_Old(CdmBase cdmBase1
, CdmBase cdmBase2
, ReferenceHolder refHolder
) throws SecurityException
, NoSuchFieldException
, IllegalArgumentException
, IllegalAccessException
{
754 List
<CdmBase
> referencingObjects
= getCdmBasesByFieldAndClass(refHolder
.otherClass
, refHolder
.propertyName
, cdmBase2
);
755 for (CdmBase referencingObject
: referencingObjects
){
756 Field referencingField
= refHolder
.otherClass
.getDeclaredField(refHolder
.propertyName
);
757 referencingField
.setAccessible(true);
758 Object test
= referencingField
.get(referencingObject
);
759 assert(test
.equals(cdmBase2
));
760 referencingField
.set(referencingObject
, cdmBase1
);
764 private void reallocateSingleItem(CdmBase cdmBase1
, CdmBase cdmBase2
, ReferenceHolder refHolder
, Set
<ICdmBase
> cloneSet
) throws SecurityException
, NoSuchFieldException
, IllegalArgumentException
, IllegalAccessException
{
765 List
<CdmBase
> referencingObjects
= getCdmBasesByFieldAndClass(refHolder
.otherClass
, refHolder
.propertyName
, cdmBase2
);
766 Session session
= getSession();
767 for (CdmBase referencingObject
: referencingObjects
){
768 if (!cloneSet
.contains(referencingObject
)){
769 String className
= refHolder
.otherClass
.getSimpleName();
770 String propertyName
= refHolder
.propertyName
;
771 String hql
= "update " + className
+ " c set c."+propertyName
+" = :newValue where c.id = :id";
772 Query query
= session
.createQuery(hql
);
773 query
.setEntity("newValue", cdmBase1
);
774 query
.setInteger("id",referencingObject
.getId());
775 int rowCount
= query
.executeUpdate();
776 logger
.debug("Rows affected: " + rowCount
);
777 session
.refresh(referencingObject
);
791 private <T
> void handleAnnotationsEtc(T cdmBase1
, T cdmBase2
, Session session
) {
792 //when handling annotations and other elements linked via @Any an JDBC errors occurs
793 //due to the unique column constraint in the association table on the column referencing
795 //For some reason not delete command is executed for the old collection
797 session
.flush(); //for debugging
798 if (cdmBase1
instanceof AnnotatableEntity
){
799 AnnotatableEntity annotatableEntity1
= (AnnotatableEntity
)cdmBase1
;
800 AnnotatableEntity annotatableEntity2
= (AnnotatableEntity
)cdmBase2
;
802 List
<Annotation
> removeListAnnotation
= new ArrayList
<Annotation
>();
803 for (Annotation annotation
: annotatableEntity2
.getAnnotations()){
804 Annotation clone
= null;
806 clone
= annotation
.clone(annotatableEntity1
);
807 } catch (CloneNotSupportedException e
) {
810 annotatableEntity1
.addAnnotation(clone
);
811 removeListAnnotation
.add(annotation
);
813 for (Annotation annotation
: removeListAnnotation
){
814 annotatableEntity2
.removeAnnotation(annotation
);
815 getSession().delete(annotation
);
818 List
<Marker
> removeListMarker
= new ArrayList
<Marker
>();
819 for (Marker marker
: annotatableEntity2
.getMarkers()){
822 clone
= marker
.clone(annotatableEntity1
);
823 } catch (CloneNotSupportedException e
) {
826 annotatableEntity1
.addMarker(clone
);
827 removeListMarker
.add(marker
);
829 for (Marker marker
: removeListMarker
){
830 annotatableEntity2
.removeMarker(marker
);
831 getSession().delete(marker
);
834 if (cdmBase1
instanceof IdentifiableEntity
){
835 IdentifiableEntity identifiableEntity1
= (IdentifiableEntity
)cdmBase1
;
836 IdentifiableEntity identifiableEntity2
= (IdentifiableEntity
)cdmBase2
;
838 List
<Extension
> removeListExtension
= new ArrayList
<Extension
>();
839 for (Extension changeObject
: (Set
<Extension
>)identifiableEntity2
.getExtensions()){
841 Extension clone
= changeObject
.clone(identifiableEntity1
);
842 identifiableEntity1
.addExtension(clone
);
843 removeListExtension
.add(changeObject
);
844 } catch (CloneNotSupportedException e
) {
849 for (Extension removeObject
: removeListExtension
){
850 identifiableEntity2
.removeExtension(removeObject
);
851 getSession().delete(removeObject
);
855 session
.saveOrUpdate(cdmBase1
);
856 session
.saveOrUpdate(cdmBase2
);
860 private <T
extends CdmBase
> void testMergeValid(T cdmBase1
, T cdmBase2
)throws IllegalArgumentException
, NullPointerException
{
861 if (cdmBase1
== null || cdmBase2
== null){
862 throw new NullPointerException("Merge arguments must not be (null)");
864 cdmBase1
= (T
)HibernateProxyHelper
.deproxy(cdmBase1
);
865 cdmBase2
= (T
)HibernateProxyHelper
.deproxy(cdmBase2
);
867 if (cdmBase1
.getClass() != cdmBase2
.getClass()){
868 throw new IllegalArgumentException("Merge arguments must be of same type");
872 //TODO Move to test classes if still needed
873 private void test() {
874 SessionFactoryImpl factory
= (SessionFactoryImpl
)getSession().getSessionFactory();
875 Type propType
= factory
.getReferencedPropertyType(BotanicalName
.class.getCanonicalName(), "titleCache");
876 Map collMetadata
= factory
.getAllCollectionMetadata();
877 Object roles
= factory
.getCollectionRolesByEntityParticipant("eu.etaxonomy.cdm.model.name.BotanicalName");
878 CollectionPersister collPersister
;
880 collPersister
= factory
.getCollectionPersister(TaxonNameBase
.class.getCanonicalName()+".annotations");
881 } catch (MappingException e
) {
882 // TODO Auto-generated catch block
885 Statistics statistics
= factory
.getStatistics();
886 Map allClassMetadata
= factory
.getAllClassMetadata();
892 public <T
extends CdmBase
> T
find(Class
<T
> clazz
, int id
){
894 session
= getSession();
895 //session = getSession().getSessionFactory().getCurrentSession();
896 Object o
= session
.get(clazz
, id
);
901 public <T
extends IMatchable
> List
<T
> findMatching(T objectToMatch
,
902 IMatchStrategy matchStrategy
) throws MatchException
{
904 List
<T
> result
= new ArrayList
<T
>();
905 if(objectToMatch
== null){
908 if (matchStrategy
== null){
909 matchStrategy
= DefaultMatchStrategy
.NewInstance(objectToMatch
.getClass());
911 result
.addAll(findMatchingNullSafe(objectToMatch
, matchStrategy
));
913 } catch (IllegalArgumentException e
) {
914 throw new MatchException(e
);
915 } catch (IllegalAccessException e
) {
916 throw new MatchException(e
);
920 private <T
extends IMatchable
> List
<T
> findMatchingNullSafe(T objectToMatch
, IMatchStrategy matchStrategy
) throws IllegalArgumentException
, IllegalAccessException
, MatchException
{
921 List
<T
> result
= new ArrayList
<T
>();
922 Session session
= getSession();
923 Class
<?
> matchClass
= objectToMatch
.getClass();
924 ClassMetadata classMetaData
= session
.getSessionFactory().getClassMetadata(matchClass
.getCanonicalName());
925 Criteria criteria
= session
.createCriteria(matchClass
);
926 boolean noMatch
= makeCriteria(objectToMatch
, matchStrategy
, classMetaData
, criteria
);
927 logger
.debug(criteria
);
929 if (noMatch
== false){
930 List
<T
> matchCandidates
= criteria
.list();
931 matchCandidates
.remove(objectToMatch
);
932 for (T matchCandidate
: matchCandidates
){
933 if (matchStrategy
.invoke(objectToMatch
, matchCandidate
)){
934 result
.add(matchCandidate
);
936 logger
.warn("Match candidate did not match: " + matchCandidate
);
945 * @param objectToMatch
946 * @param matchStrategy
947 * @param classMetaData
950 * @throws IllegalAccessException
951 * @throws MatchException
953 private <T
> boolean makeCriteria(T objectToMatch
,
954 IMatchStrategy matchStrategy
, ClassMetadata classMetaData
,
955 Criteria criteria
) throws IllegalAccessException
, MatchException
{
956 Matching matching
= matchStrategy
.getMatching();
957 boolean noMatch
= false;
958 Map
<String
, List
<MatchMode
>> replaceMatchers
= new HashMap
<String
, List
<MatchMode
>>();
959 for (CacheMatcher cacheMatcher
: matching
.getCacheMatchers()){
960 boolean cacheProtected
= (Boolean
)cacheMatcher
.getProtectedField(matching
).get(objectToMatch
);
961 if (cacheProtected
== true){
962 String cacheValue
= (String
)cacheMatcher
.getField().get(objectToMatch
);
963 if (StringUtils
.isBlank(cacheValue
)){
964 return true; //no match
966 criteria
.add(Restrictions
.eq(cacheMatcher
.getPropertyName(), cacheValue
));
967 criteria
.add(Restrictions
.eq(cacheMatcher
.getProtectedPropertyName(), cacheProtected
));
969 List
<DoubleResult
<String
, MatchMode
>> replacementModes
= cacheMatcher
.getReplaceMatchModes(matching
);
970 for (DoubleResult
<String
, MatchMode
> replacementMode
: replacementModes
){
971 String propertyName
= replacementMode
.getFirstResult();
972 List
<MatchMode
> replaceMatcherList
= replaceMatchers
.get(propertyName
);
973 if (replaceMatcherList
== null){
974 replaceMatcherList
= new ArrayList
<MatchMode
>();
975 replaceMatchers
.put(propertyName
, replaceMatcherList
);
977 replaceMatcherList
.add(replacementMode
.getSecondResult());
983 for (FieldMatcher fieldMatcher
: matching
.getFieldMatchers(false)){
984 String propertyName
= fieldMatcher
.getPropertyName();
985 Type propertyType
= classMetaData
.getPropertyType(propertyName
);
986 Object value
= fieldMatcher
.getField().get(objectToMatch
);
987 List
<MatchMode
> matchModes
= new ArrayList
<MatchMode
>();
988 matchModes
.add(fieldMatcher
.getMatchMode());
989 if (replaceMatchers
.get(propertyName
) != null){
990 matchModes
.addAll(replaceMatchers
.get(propertyName
));
993 boolean isIgnore
= false;
994 for (MatchMode matchMode
: matchModes
){
995 isIgnore
|= matchMode
.isIgnore(value
);
998 if (propertyType
.isComponentType()){
999 matchComponentType(criteria
, fieldMatcher
, propertyName
, value
, matchModes
);
1001 noMatch
= matchNonComponentType(criteria
, fieldMatcher
, propertyName
, value
, matchModes
, propertyType
);
1013 * @param fieldMatcher
1014 * @param propertyName
1017 * @throws MatchException
1018 * @throws IllegalAccessException
1020 private void matchComponentType(Criteria criteria
,
1021 FieldMatcher fieldMatcher
, String propertyName
, Object value
,
1022 List
<MatchMode
> matchModes
) throws MatchException
, IllegalAccessException
{
1024 boolean requiresSecondNull
= requiresSecondNull(matchModes
, value
);
1025 if (requiresSecondNull
){
1026 criteria
.add(Restrictions
.isNull(propertyName
));
1029 logger
.warn("Component type not yet implemented for (null) value: " + propertyName
);
1030 throw new MatchException("Component type not yet fully implemented for (null) value. Property: " + propertyName
);
1033 Class
<?
> componentClass
= fieldMatcher
.getField().getType();
1034 Map
<String
, Field
> fields
= CdmUtils
.getAllFields(componentClass
, Object
.class, false, false, true, false);
1035 for (String fieldName
: fields
.keySet()){
1036 String restrictionPath
= propertyName
+"."+fieldName
;
1037 Object componentValue
= fields
.get(fieldName
).get(value
);
1038 //TODO diffentiate matchMode
1039 createCriterion(criteria
, restrictionPath
, componentValue
, matchModes
);
1044 private boolean matchNonComponentType(Criteria criteria
,
1045 FieldMatcher fieldMatcher
, String propertyName
, Object value
,
1046 List
<MatchMode
> matchModes
, Type propertyType
) throws HibernateException
, DataAccessException
, MatchException
, IllegalAccessException
{
1047 boolean noMatch
= false;
1048 if (isRequired(matchModes
) && value
== null){
1051 }else if (requiresSecondNull(matchModes
,value
)){
1052 criteria
.add(Restrictions
.isNull(propertyName
));
1054 if (isMatch(matchModes
)){
1055 if (propertyType
.isCollectionType()){
1056 //TODO collection not yet handled for match
1058 int joinType
= CriteriaSpecification
.INNER_JOIN
;
1059 if (! requiresSecondValue(matchModes
,value
)){
1060 joinType
= CriteriaSpecification
.LEFT_JOIN
;
1062 Criteria matchCriteria
= criteria
.createCriteria(propertyName
, joinType
).add(Restrictions
.isNotNull("id"));
1063 Class matchClass
= value
.getClass();
1064 if (IMatchable
.class.isAssignableFrom(matchClass
)){
1065 IMatchStrategy valueMatchStrategy
= DefaultMatchStrategy
.NewInstance((Class
<IMatchable
>)matchClass
);
1066 ClassMetadata valueClassMetaData
= getSession().getSessionFactory().getClassMetadata(matchClass
.getCanonicalName());;
1067 noMatch
= makeCriteria(value
, valueMatchStrategy
, valueClassMetaData
, matchCriteria
);
1069 logger
.error("Class to match (" + matchClass
+ ") is not of type IMatchable");
1070 throw new MatchException("Class to match (" + matchClass
+ ") is not of type IMatchable");
1073 }else if (isEqual(matchModes
)){
1074 createCriterion(criteria
, propertyName
, value
, matchModes
);
1076 logger
.warn("Unhandled match mode: " + matchModes
+ ", value: " + (value
==null?
"null":value
));
1084 * @param propertyName
1087 * @throws MatchException
1089 private void createCriterion(Criteria criteria
, String propertyName
,
1090 Object value
, List
<MatchMode
> matchModes
) throws MatchException
{
1091 Criterion finalRestriction
= null;
1092 Criterion equalRestriction
= Restrictions
.eq(propertyName
, value
);
1093 Criterion nullRestriction
= Restrictions
.isNull(propertyName
);
1094 if (this.requiresSecondValue(matchModes
, value
)){
1095 finalRestriction
= equalRestriction
;
1096 }else if (requiresSecondNull(matchModes
, value
) ){
1097 finalRestriction
= nullRestriction
;
1099 finalRestriction
= Restrictions
.or(equalRestriction
, nullRestriction
);
1101 //return finalRestriction;
1102 criteria
.add(finalRestriction
);
1109 * @throws MatchException
1111 private boolean requiresSecondNull(List
<MatchMode
> matchModes
, Object value
) throws MatchException
{
1112 boolean result
= true;
1113 for (MatchMode matchMode
: matchModes
){
1114 result
&= matchMode
.requiresSecondNull(value
);
1123 * @throws MatchException
1125 private boolean requiresSecondValue(List
<MatchMode
> matchModes
, Object value
) throws MatchException
{
1126 boolean result
= true;
1127 for (MatchMode matchMode
: matchModes
){
1128 result
&= matchMode
.requiresSecondValue(value
);
1137 * @throws MatchException
1139 private boolean isRequired(List
<MatchMode
> matchModes
) throws MatchException
{
1140 boolean result
= true;
1141 for (MatchMode matchMode
: matchModes
){
1142 result
&= matchMode
.isRequired();
1148 * Returns true if at least one match mode is of typ MATCH_XXX
1152 * @throws MatchException
1154 private boolean isMatch(List
<MatchMode
> matchModes
) throws MatchException
{
1155 boolean result
= false;
1156 for (MatchMode matchMode
: matchModes
){
1157 result
|= matchMode
.isMatch();
1163 * Returns true if at least one match mode is of typ EQUAL_XXX
1167 * @throws MatchException
1169 private boolean isEqual(List
<MatchMode
> matchModes
) throws MatchException
{
1170 boolean result
= false;
1171 for (MatchMode matchMode
: matchModes
){
1172 result
|= matchMode
.isEqual();
1178 * @see eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao#saveMetaData(eu.etaxonomy.cdm.model.common.CdmMetaData)
1180 public void saveMetaData(CdmMetaData cdmMetaData
) {
1181 getSession().saveOrUpdate(cdmMetaData
);
1185 * @see eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao#getMetaData()
1187 public List
<CdmMetaData
> getMetaData() {
1188 Session session
= getSession();
1189 Criteria crit
= session
.createCriteria(CdmMetaData
.class);
1190 List
<CdmMetaData
> results
= crit
.list();
1195 public PersistentCollection
initializeCollection(PersistentCollection col
) {
1196 Session session
= getSession();
1197 col
.setCurrentSession((SessionImplementor
) session
);
1199 if(!((SessionImplementor
)session
).getPersistenceContext().getCollectionEntries().containsKey(col
)) {
1200 ((SessionImplementor
)session
).getPersistenceContext().addUninitializedDetachedCollection(
1201 ((SessionImplementor
)session
).getFactory().getCollectionPersister( col
.getRole() ),col
);
1203 col
.forceInitialization();
1204 logger
.debug("initialising persistent collection with with role : " + col
.getRole() + " and key : " + col
.getKey());
1209 public boolean isEmpty(PersistentCollection col
) {
1210 return initializeCollection(col
).empty();
1214 public int size(PersistentCollection col
) {
1215 logger
.debug("remote size() - for role : " + col
.getRole() + " and key : " + col
.getKey());
1216 initializeCollection(col
);
1217 SessionImplementor session
= (SessionImplementor
)getSession();
1218 CollectionEntry entry
= session
.getPersistenceContext().getCollectionEntry(col
);
1220 if ( entry
!= null ) {
1222 CollectionPersister persister
= entry
.getLoadedPersister();
1223 return persister
.getSize( entry
.getLoadedKey(), session
);
1229 public Object
get(PersistentCollection col
, int index
) {
1230 logger
.debug("remote get() - for role : " + col
.getRole() + " and key : " + col
.getKey());
1231 initializeCollection(col
);
1232 SessionImplementor session
= (SessionImplementor
)getSession();
1233 CollectionEntry entry
= session
.getPersistenceContext().getCollectionEntry(col
);
1235 if ( entry
!= null ) {
1237 CollectionPersister persister
= entry
.getLoadedPersister();
1238 return persister
.getElementByIndex(entry
.getLoadedKey(), index
, session
, col
);
1241 //FIXME:Remoting Should we not be throwing an exception here ?
1246 public boolean contains(PersistentCollection col
, Object element
) {
1247 logger
.debug("remote contains() - for role : " + col
.getRole() + " and key : " + col
.getKey());
1248 initializeCollection(col
);
1249 SessionImplementor session
= (SessionImplementor
)getSession();
1250 CollectionEntry entry
= session
.getPersistenceContext().getCollectionEntry(col
);
1252 if ( entry
!= null ) {
1254 CollectionPersister persister
= entry
.getLoadedPersister();
1255 return persister
.elementExists(entry
.getLoadedKey(), element
, session
);
1257 //FIXME:Remoting Should we not be throwing an exception here ?
1262 public boolean containsKey(PersistentCollection col
, Object key
) {
1263 logger
.debug("remote containsKey() - for role : " + col
.getRole() + " and key : " + col
.getKey());
1264 initializeCollection(col
);
1265 SessionImplementor session
= (SessionImplementor
)getSession();
1266 CollectionEntry entry
= session
.getPersistenceContext().getCollectionEntry(col
);
1268 if ( entry
!= null ) {
1270 CollectionPersister persister
= entry
.getLoadedPersister();
1271 return persister
.indexExists(entry
.getLoadedKey(), key
, session
);
1273 //FIXME:Remoting Should we not be throwing an exception here ?
1279 public boolean containsValue(PersistentCollection col
, Object element
) {
1280 return contains(col
, element
);