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();
128 Criteria criteria
= session
.createCriteria(clazz
);
129 criteria
.add(Restrictions
.eq(propertyName
, referencedCdmBase
));
130 return criteria
.list();
134 public List
<CdmBase
> getCdmBasesWithItemInCollection(Class itemClass
, Class clazz
, String propertyName
, CdmBase item
){
135 Session session
= super.getSession();
136 String thisClassStr
= itemClass
.getSimpleName();
137 String otherClassStr
= clazz
.getSimpleName();
138 String queryStr
= " SELECT other FROM "+ thisClassStr
+ " this, " + otherClassStr
+ " other " +
139 " WHERE this = :referencedObject AND this member of other."+propertyName
;
140 Query query
= session
.createQuery(queryStr
).setEntity("referencedObject", item
);
141 List
<CdmBase
> result
= query
.list();
146 public Set
<Class
<?
extends CdmBase
>> getAllCdmClasses(boolean includeAbstractClasses
){
147 Set
<Class
<?
extends CdmBase
>> result
= new HashSet
<Class
<?
extends CdmBase
>>();
149 SessionFactory sessionFactory
= getSession().getSessionFactory();
150 Map
<?
,?
> allClassMetadata
= sessionFactory
.getAllClassMetadata();
151 Collection
<?
> keys
= allClassMetadata
.keySet();
152 for (Object oKey
: keys
){
153 if (oKey
instanceof String
){
154 String strKey
= (String
)oKey
;
155 if (! strKey
.endsWith("_AUD")){
157 Class clazz
= Class
.forName(strKey
);
158 boolean isAbstractClass
= Modifier
.isAbstract(clazz
.getModifiers());
159 if (! isAbstractClass
|| includeAbstractClasses
){
162 } catch (ClassNotFoundException e
) {
163 logger
.warn("Class not found: " + strKey
);
167 logger
.warn("key is not of type String: " + oKey
);
174 public Set
<CdmBase
> getReferencingObjects(CdmBase referencedCdmBase
){
175 Set
<CdmBase
> result
= new HashSet
<CdmBase
>();
177 referencedCdmBase
= (CdmBase
)HibernateProxyHelper
.deproxy(referencedCdmBase
);
178 Class
<?
extends CdmBase
> referencedClass
= referencedCdmBase
.getClass();
180 Set
<ReferenceHolder
> holderSet
= referenceMap
.get(referencedClass
);
181 if (holderSet
== null){
182 holderSet
= makeHolderSet(referencedClass
);
183 referenceMap
.put(referencedClass
, holderSet
);
185 for (ReferenceHolder refHolder
: holderSet
){
186 handleReferenceHolder(referencedCdmBase
, result
, refHolder
);
189 } catch (Exception e
) {
191 throw new RuntimeException(e
);
197 * @param referencedCdmBase
201 private void handleReferenceHolder(CdmBase referencedCdmBase
,
202 Set
<CdmBase
> result
, ReferenceHolder refHolder
) {
203 boolean isCollection
= refHolder
.isCollection();
205 result
.addAll(getCdmBasesWithItemInCollection(refHolder
.itemClass
, refHolder
.otherClass
, refHolder
.propertyName
, referencedCdmBase
));
207 result
.addAll(getCdmBasesByFieldAndClass(refHolder
.otherClass
, refHolder
.propertyName
, referencedCdmBase
));
213 * @param referencedClass
215 * @throws NoSuchFieldException
216 * @throws ClassNotFoundException
218 private Set
<ReferenceHolder
> makeHolderSet(Class
<?
> referencedClass
) throws ClassNotFoundException
, NoSuchFieldException
{
219 Set
<ReferenceHolder
> result
= new HashSet
<ReferenceHolder
>();
222 if (allCdmClasses
== null){
223 allCdmClasses
= getAllCdmClasses(false); //findAllCdmClasses();
225 //referencedCdmBase = (CdmBase)HibernateProxyHelper.deproxy(referencedCdmBase);
226 SessionFactory sessionFactory
= getSession().getSessionFactory();
229 for (Class
<?
extends CdmBase
> cdmClass
: allCdmClasses
){
230 ClassMetadata classMetadata
= sessionFactory
.getClassMetadata(cdmClass
);
231 Type
[] propertyTypes
= classMetadata
.getPropertyTypes();
233 for (Type propertyType
: propertyTypes
){
234 String propertyName
= classMetadata
.getPropertyNames()[propertyNr
];
235 makePropertyType(result
, referencedClass
, sessionFactory
, cdmClass
, propertyType
, propertyName
, false);
244 * @param referencedCdmBase
246 * @param referencedClass
247 * @param sessionFactory
249 * @param propertyType
250 * @param propertyName
251 * @throws ClassNotFoundException
252 * @throws NoSuchFieldException
254 private void makePropertyType(
255 // CdmBase referencedCdmBase,
256 Set
<ReferenceHolder
> result
,
257 Class
<?
> referencedClass
,
258 SessionFactory sessionFactory
, Class
<?
extends CdmBase
> cdmClass
,
259 Type propertyType
, String propertyName
, boolean isCollection
)
260 throws ClassNotFoundException
, NoSuchFieldException
{
263 if (propertyType
.isEntityType()){
264 EntityType entityType
= (EntityType
)propertyType
;
265 String associatedEntityName
= entityType
.getAssociatedEntityName();
266 Class
<?
> entityClass
= Class
.forName(associatedEntityName
);
267 if (entityClass
.isInterface()){
268 logger
.debug("There is an interface");
270 if (entityClass
.isAssignableFrom(referencedClass
)){
271 makeSingleProperty(referencedClass
, entityClass
, propertyName
, cdmClass
, result
, isCollection
);
273 }else if (propertyType
.isCollectionType()){
274 CollectionType collectionType
= (CollectionType
)propertyType
;
275 //String role = collectionType.getRole();
276 Type elType
= collectionType
.getElementType((SessionFactoryImplementor
)sessionFactory
);
277 makePropertyType(result
, referencedClass
, sessionFactory
, cdmClass
, elType
, propertyName
, true);
278 }else if (propertyType
.isAnyType()){
279 // AnyType anyType = (AnyType)propertyType;
280 Field field
= cdmClass
.getDeclaredField(propertyName
);
281 Class
<?
> returnType
= field
.getType();
282 if (returnType
.isInterface()){
283 logger
.debug("There is an interface");
285 if (returnType
.isAssignableFrom(referencedClass
)){
286 makeSingleProperty(referencedClass
, returnType
, propertyName
, cdmClass
, result
, isCollection
);
288 }else if (propertyType
.isComponentType()){
289 ComponentType componentType
= (ComponentType
)propertyType
;
290 Type
[] subTypes
= componentType
.getSubtypes();
291 // Field field = cdmClass.getDeclaredField(propertyName);
292 // Class returnType = field.getType();
294 for (Type subType
: subTypes
){
295 String subPropertyName
= componentType
.getPropertyNames()[propertyNr
];
296 if (!isNoDoType(subType
)){
297 logger
.warn("SubType not yet handled: " + subType
);
299 // handlePropertyType(referencedCdmBase, result, referencedClass,
300 // sessionFactory, cdmClass, subType, subPropertyName, isCollection);
303 }else if (isNoDoType(propertyType
)){
306 logger
.warn("propertyType not yet handled: " + propertyType
.getName());
309 // if (! type.isInterface()){
310 // if (referencedClass.isAssignableFrom(type)||
311 // type.isAssignableFrom(referencedClass) && CdmBase.class.isAssignableFrom(type)){
312 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
315 // }else if (type.isAssignableFrom(referencedClass)){
316 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
320 private boolean makeSingleProperty(Class itemClass
, Class
<?
> type
, String propertyName
, Class cdmClass
, Set
<ReferenceHolder
> result
,/*CdmBase item,*/ boolean isCollection
){
321 String fieldName
= StringUtils
.rightPad(propertyName
, 30);
322 String className
= StringUtils
.rightPad(cdmClass
.getSimpleName(), 30);
323 String returnTypeName
= StringUtils
.rightPad(type
.getSimpleName(), 30);
325 // logger.debug(fieldName + "\t\t" + className + "\t\t" + returnTypeName);
326 ReferenceHolder refHolder
= new ReferenceHolder();
327 refHolder
.propertyName
= propertyName
;
328 refHolder
.otherClass
= cdmClass
;
329 refHolder
.itemClass
= (isCollection ? itemClass
: null) ;
330 result
.add(refHolder
);
335 * @param propertyType
338 private boolean isNoDoType(Type propertyType
) {
339 boolean result
= false;
340 Class
<?
>[] classes
= new Class
[]{
341 PersistentDateTime
.class,
342 WSDLDefinitionUserType
.class,
344 PartialUserType
.class,
348 MaterializedClobType
.class,
351 SerializableType
.class,
358 Set
<String
> classNames
= new HashSet
<String
>();
359 for (Class
<?
> clazz
: classes
){
360 classNames
.add(clazz
.getCanonicalName());
361 if (clazz
== propertyType
.getClass()){
365 String propertyTypeClassName
= propertyType
.getName();
366 if (classNames
.contains(propertyTypeClassName
)){
373 public List
<CdmBase
> getHqlResult(String hqlQuery
){
374 Query query
= getSession().createQuery(hqlQuery
);
375 List
<CdmBase
> result
= query
.list();
380 public Query
getHqlQuery(String hqlQuery
){
381 Query query
= getSession().createQuery(hqlQuery
);
386 public <T
extends CdmBase
> void merge(T cdmBase1
, T cdmBase2
, IMergeStrategy mergeStrategy
) throws MergeException
{
387 Class
<T
> clazz
= (Class
<T
>)cdmBase1
.getClass();
388 SessionImpl session
= (SessionImpl
) getSession();
389 SessionFactory sessionFactory
= session
.getSessionFactory();
390 if (mergeStrategy
== null){
391 mergeStrategy
= DefaultMergeStrategy
.NewInstance(cdmBase1
.getClass());
394 //test null and types
395 testMergeValid(cdmBase1
, cdmBase2
);
401 Set
<ICdmBase
> deleteSet
= new HashSet
<ICdmBase
>();
402 Set
<ICdmBase
> cloneSet
= new HashSet
<ICdmBase
>();
403 if (cdmBase1
instanceof IMergable
){
404 IMergable mergable1
= (IMergable
)cdmBase1
;
405 IMergable mergable2
= (IMergable
)cdmBase2
;
406 deleteSet
= mergeStrategy
.invoke(mergable1
, mergable2
, cloneSet
);
407 //session.saveOrUpdate(mergable1);
410 //((IMergable)cdmBase1).mergeInto(cdmBase2, DefaultMergeStrategy.NewInstance(cdmBase1.getClass()));
412 mergeExternal(cdmBase1
, cdmBase2
, clazz
, session
);
416 if (cdmBase2
.getId() > 0){
417 session
.saveOrUpdate(cdmBase2
);
418 //rearrange references to cdmBase2
419 reallocateReferences(cdmBase1
, cdmBase2
, sessionFactory
, clazz
, cloneSet
);
422 //remove deleted objects
424 //session.delete(null, mergable2, true, null);
425 session
.delete(cdmBase2
);
426 for (ICdmBase toBeDeleted
: deleteSet
){
427 logger
.debug("Delete " + toBeDeleted
);
428 if (toBeDeleted
!= cdmBase2
){
429 session
.delete(toBeDeleted
);
437 } catch (Exception e
) {
438 throw new MergeException(e
);
448 * @param sessionFactory
449 * @throws MergeException
450 * @throws ClassNotFoundException
451 * @throws NoSuchFieldException
453 private <T
extends CdmBase
> void mergeExternal(T cdmBase1
, T cdmBase2
, Class
<T
> clazz
,
454 Session session
) throws MergeException
{
456 logger
.warn("Merge external");
457 handleAnnotationsEtc(cdmBase1
, cdmBase2
, session
);
459 SessionFactoryImpl sessionFactory
= (SessionFactoryImpl
) session
.getSessionFactory();
461 Map
<String
, ClassMetadata
> allClassMetadata
= sessionFactory
.getAllClassMetadata();
464 getCollectionRoles(clazz
, sessionFactory
);
466 TaxonNameBase name1
= BotanicalName
.NewInstance(null);
467 name1
.getTaxonBases();
469 Type propType
= sessionFactory
.getReferencedPropertyType(BotanicalName
.class.getCanonicalName(), "taxonBases");
470 Map collMetadata
= sessionFactory
.getAllCollectionMetadata();
471 //roles = sessionFactory.getCollectionRolesByEntityParticipant("eu.etaxonomy.cdm.model.name.BotanicalName");
472 CollectionPersister collPersister
;
474 collPersister
= sessionFactory
.getCollectionPersister(TaxonNameBase
.class.getCanonicalName()+".annotations");
475 } catch (MappingException e
) {
476 // TODO Auto-generated catch block
479 // Statistics statistics = sessionFactory.getStatistics();
481 ClassMetadata taxonMetaData
= sessionFactory
.getClassMetadata(Taxon
.class);
482 String ename
= taxonMetaData
.getEntityName();
484 Reference ref
= sessionFactory
.getReference();
486 } catch (Exception e
) {
487 // TODO Auto-generated catch block
492 ClassMetadata classMetadata
= getSession().getSessionFactory().getClassMetadata(clazz
);
493 Type
[] propertyTypes
= classMetadata
.getPropertyTypes();
495 for (Type propertyType
: propertyTypes
){
496 String propertyName
= classMetadata
.getPropertyNames()[propertyNr
];
497 logger
.debug(propertyName
);
498 makeMergeProperty(cdmBase1
, cdmBase2
, propertyType
, propertyName
, sessionFactory
, false);
501 Set
<String
> collectionRoles
;
502 if (classMetadata
instanceof AbstractEntityPersister
){
503 AbstractEntityPersister persister
= (AbstractEntityPersister
)classMetadata
;
504 String rootName
= persister
.getRootEntityName();
505 collectionRoles
= sessionFactory
.getCollectionRolesByEntityParticipant(rootName
);
506 for (String collectionRole
: collectionRoles
){
507 CollectionMetadata collMetadata2
= sessionFactory
.getCollectionMetadata(collectionRole
);
508 String role
= collMetadata2
.getRole();
509 Type elType
= collMetadata2
.getElementType();
518 * @param sessionFactory
520 private <T
> Set
<String
> getCollectionRoles(Class
<T
> clazz
,
521 SessionFactoryImpl sessionFactory
) {
522 Set
<String
> collectionRoles
= null;
523 ClassMetadata classMetaData
= sessionFactory
.getClassMetadata(clazz
);
524 if (classMetaData
instanceof AbstractEntityPersister
){
525 AbstractEntityPersister persister
= (AbstractEntityPersister
)classMetaData
;
526 String rootName
= persister
.getRootEntityName();
527 collectionRoles
= sessionFactory
.getCollectionRolesByEntityParticipant(rootName
);
528 for (String collectionRole
: collectionRoles
){
529 CollectionMetadata collMetadata
= sessionFactory
.getCollectionMetadata(collectionRole
);
530 CollectionPersister collPersister
= sessionFactory
.getCollectionPersister(collectionRole
);
534 logger
.warn("Class metadata is not of type AbstractEntityPersister");
535 throw new UnhandledException("Class metadata is not of type AbstractEntityPersister", null);
537 return collectionRoles
;
541 private <T
extends CdmBase
> void makeMergeProperty(T cdmBase1
, T cdmBase2
, Type propertyType
, String propertyName
, SessionFactoryImpl sessionFactory
, boolean isCollection
) throws MergeException
545 Class
<T
> clazz
= (Class
<T
>)cdmBase1
.getClass();
546 if (isNoDoType(propertyType
)){
548 }else if (propertyType
.isEntityType()){
549 //Field field = clazz.getField(propertyName);
550 EntityType entityType
= (EntityType
)propertyType
;
551 String associatedEntityName
= entityType
.getAssociatedEntityName();
552 Class entityClass
= Class
.forName(associatedEntityName
);
553 // Type refPropType = sessionFactory.getReferencedPropertyType(entityClass.getCanonicalName(), propertyName);
554 Set
<String
> collectionRoles
= getCollectionRoles(clazz
, sessionFactory
);
555 for (String collectionRole
: collectionRoles
){
556 CollectionMetadata collMetadata
= sessionFactory
.getCollectionMetadata(collectionRole
);
557 String role
= collMetadata
.getRole();
562 // if (entityClass.isInterface()){
563 // logger.debug("So ein interface");
565 // if (entityClass.isAssignableFrom(clazz)){
566 // makeSingleProperty(referencedClass, entityClass, propertyName, cdmClass, result, isCollection);
568 }else if (propertyType
.isCollectionType()){
569 CollectionType collectionType
= (CollectionType
)propertyType
;
570 String role
= collectionType
.getRole();
571 Type elType
= collectionType
.getElementType((SessionFactoryImplementor
)sessionFactory
);
572 String n
= collectionType
.getAssociatedEntityName(sessionFactory
);
573 CollectionMetadata collMetadata
= sessionFactory
.getCollectionMetadata(role
);
574 if (collMetadata
instanceof OneToManyPersister
){
575 OneToManyPersister oneManyPersister
= (OneToManyPersister
)collMetadata
;
576 String className
= oneManyPersister
.getOwnerEntityName();
577 Class
<?
> myClass
= Class
.forName(className
);
578 Field field
= myClass
.getDeclaredField(propertyName
);
579 field
.setAccessible(true);
581 if (collectionType
instanceof SetType
){
582 Set set2
= (Set
)field
.get(cdmBase2
);
583 Set
<Object
> set1
= (Set
<Object
>)field
.get(cdmBase1
);
584 for (Object obj2
: set2
){
588 } catch (IllegalArgumentException e
) {
589 // TODO Auto-generated catch block
591 } catch (IllegalAccessException e
) {
592 // TODO Auto-generated catch block
599 // makePropertyType(result, referencedClass, sessionFactory, cdmClass, elType, propertyName, true);
600 }else if (propertyType
.isAnyType()){
601 AnyType anyType
= (AnyType
)propertyType
;
602 Field field
= clazz
.getDeclaredField(propertyName
);
603 Class returnType
= field
.getType();
604 // if (returnType.isInterface()){
605 // logger.debug("So ein interface");
607 // if (returnType.isAssignableFrom(referencedClass)){
608 // makeSingleProperty(referencedClass, returnType, propertyName, cdmClass, result, isCollection);
610 }else if (propertyType
.isComponentType()){
611 ComponentType componentType
= (ComponentType
)propertyType
;
612 Type
[] subTypes
= componentType
.getSubtypes();
613 // Field field = cdmClass.getDeclaredField(propertyName);
614 // Class returnType = field.getType();
616 for (Type subType
: subTypes
){
617 String subPropertyName
= componentType
.getPropertyNames()[propertyNr
];
618 if (!isNoDoType(subType
)){
619 logger
.warn("SubType not yet handled: " + subType
);
621 // handlePropertyType(referencedCdmBase, result, referencedClass,
622 // sessionFactory, cdmClass, subType, subPropertyName, isCollection);
626 logger
.warn("propertyType not yet handled: " + propertyType
.getName());
629 // if (! type.isInterface()){
630 // if (referencedClass.isAssignableFrom(type)||
631 // type.isAssignableFrom(referencedClass) && CdmBase.class.isAssignableFrom(type)){
632 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
635 // }else if (type.isAssignableFrom(referencedClass)){
636 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
637 } catch (Exception e
) {
638 throw new MergeException(e
);
645 private void reallocateReferences(CdmBase cdmBase1
, CdmBase cdmBase2
, SessionFactory sessionFactory
, Class clazz
, Set
<ICdmBase
> cloneSet
){
647 Set
<ReferenceHolder
> holderSet
= referenceMap
.get(clazz
);
648 if (holderSet
== null){
649 holderSet
= makeHolderSet(clazz
);
650 referenceMap
.put(clazz
, holderSet
);
652 for (ReferenceHolder refHolder
: holderSet
){
653 reallocateByHolder(cdmBase1
, cdmBase2
, refHolder
, cloneSet
);
656 } catch (Exception e
) {
658 throw new RuntimeException(e
);
666 * @throws MergeException
668 private void reallocateByHolder(CdmBase cdmBase1
, CdmBase cdmBase2
, ReferenceHolder refHolder
, Set
<ICdmBase
> cloneSet
) throws MergeException
{
670 if (refHolder
.isCollection()){
671 reallocateCollection(cdmBase1
, cdmBase2
, refHolder
, cloneSet
);
673 reallocateSingleItem(cdmBase1
, cdmBase2
, refHolder
, cloneSet
);
675 } catch (Exception e
) {
676 throw new MergeException("Error during reallocation of references to merge object: " + cdmBase2
, e
);
686 * @throws MergeException
687 * @throws NoSuchFieldException
688 * @throws SecurityException
689 * @throws IllegalAccessException
690 * @throws IllegalArgumentException
691 * @throws InvocationTargetException
693 private void reallocateCollection(CdmBase cdmBase1
, CdmBase cdmBase2
,
694 ReferenceHolder refHolder
, Set
<ICdmBase
> cloneSet
) throws MergeException
, SecurityException
, NoSuchFieldException
, IllegalArgumentException
, IllegalAccessException
, InvocationTargetException
{
695 List
<CdmBase
> list
= getCdmBasesWithItemInCollection(refHolder
.itemClass
, refHolder
.otherClass
, refHolder
.propertyName
, cdmBase2
);
696 for (CdmBase referencingObject
: list
){
697 Field referencingField
= getFieldRecursive(refHolder
.otherClass
, refHolder
.propertyName
);
698 referencingField
.setAccessible(true);
699 Object collection
= referencingField
.get(referencingObject
);
700 if (! (collection
instanceof Collection
)){
701 throw new MergeException ("Reallocation of collections for collection other than set and list not yet implemented");
703 Method addMethod
= DefaultMergeStrategy
.getAddMethod(referencingField
, false);
704 Method removeMethod
= DefaultMergeStrategy
.getAddMethod(referencingField
, true);
705 addMethod
.invoke(referencingObject
, cdmBase1
);
706 removeMethod
.invoke(referencingObject
, cdmBase2
);
710 private Field
getFieldRecursive(Class clazz
, String propertyName
) throws NoSuchFieldException
{
712 return clazz
.getDeclaredField(propertyName
);
713 } catch (NoSuchFieldException e
) {
714 Class superClass
= clazz
.getSuperclass();
715 if (CdmBase
.class.isAssignableFrom(superClass
)){
716 return getFieldRecursive(superClass
, propertyName
);
724 * @throws NoSuchFieldException
725 * @throws SecurityException
726 * @throws IllegalAccessException
727 * @throws IllegalArgumentException
730 private void reallocateSingleItem_Old(CdmBase cdmBase1
, CdmBase cdmBase2
, ReferenceHolder refHolder
) throws SecurityException
, NoSuchFieldException
, IllegalArgumentException
, IllegalAccessException
{
731 List
<CdmBase
> referencingObjects
= getCdmBasesByFieldAndClass(refHolder
.otherClass
, refHolder
.propertyName
, cdmBase2
);
732 for (CdmBase referencingObject
: referencingObjects
){
733 Field referencingField
= refHolder
.otherClass
.getDeclaredField(refHolder
.propertyName
);
734 referencingField
.setAccessible(true);
735 Object test
= referencingField
.get(referencingObject
);
736 assert(test
.equals(cdmBase2
));
737 referencingField
.set(referencingObject
, cdmBase1
);
741 private void reallocateSingleItem(CdmBase cdmBase1
, CdmBase cdmBase2
, ReferenceHolder refHolder
, Set
<ICdmBase
> cloneSet
) throws SecurityException
, NoSuchFieldException
, IllegalArgumentException
, IllegalAccessException
{
742 List
<CdmBase
> referencingObjects
= getCdmBasesByFieldAndClass(refHolder
.otherClass
, refHolder
.propertyName
, cdmBase2
);
743 Session session
= getSession();
744 for (CdmBase referencingObject
: referencingObjects
){
745 if (!cloneSet
.contains(referencingObject
)){
746 String className
= refHolder
.otherClass
.getSimpleName();
747 String propertyName
= refHolder
.propertyName
;
748 String hql
= "update " + className
+ " c set c."+propertyName
+" = :newValue where c.id = :id";
749 Query query
= session
.createQuery(hql
);
750 query
.setEntity("newValue", cdmBase1
);
751 query
.setInteger("id",referencingObject
.getId());
752 int rowCount
= query
.executeUpdate();
753 logger
.debug("Rows affected: " + rowCount
);
754 session
.refresh(referencingObject
);
768 private <T
> void handleAnnotationsEtc(T cdmBase1
, T cdmBase2
, Session session
) {
769 //when handling annotations and other elements linked via @Any an JDBC errors occurs
770 //due to the unique column constraint in the association table on the column referencing
772 //For some reason not delete command is executed for the old collection
774 session
.flush(); //for debugging
775 if (cdmBase1
instanceof AnnotatableEntity
){
776 AnnotatableEntity annotatableEntity1
= (AnnotatableEntity
)cdmBase1
;
777 AnnotatableEntity annotatableEntity2
= (AnnotatableEntity
)cdmBase2
;
779 List
<Annotation
> removeListAnnotation
= new ArrayList
<Annotation
>();
780 for (Annotation annotation
: annotatableEntity2
.getAnnotations()){
781 Annotation clone
= null;
783 clone
= annotation
.clone(annotatableEntity1
);
784 } catch (CloneNotSupportedException e
) {
787 annotatableEntity1
.addAnnotation(clone
);
788 removeListAnnotation
.add(annotation
);
790 for (Annotation annotation
: removeListAnnotation
){
791 annotatableEntity2
.removeAnnotation(annotation
);
792 getSession().delete(annotation
);
795 List
<Marker
> removeListMarker
= new ArrayList
<Marker
>();
796 for (Marker marker
: annotatableEntity2
.getMarkers()){
799 clone
= marker
.clone(annotatableEntity1
);
800 } catch (CloneNotSupportedException e
) {
803 annotatableEntity1
.addMarker(clone
);
804 removeListMarker
.add(marker
);
806 for (Marker marker
: removeListMarker
){
807 annotatableEntity2
.removeMarker(marker
);
808 getSession().delete(marker
);
811 if (cdmBase1
instanceof IdentifiableEntity
){
812 IdentifiableEntity identifiableEntity1
= (IdentifiableEntity
)cdmBase1
;
813 IdentifiableEntity identifiableEntity2
= (IdentifiableEntity
)cdmBase2
;
815 List
<Extension
> removeListExtension
= new ArrayList
<Extension
>();
816 for (Extension changeObject
: (Set
<Extension
>)identifiableEntity2
.getExtensions()){
818 Extension clone
= changeObject
.clone(identifiableEntity1
);
819 identifiableEntity1
.addExtension(clone
);
820 removeListExtension
.add(changeObject
);
821 } catch (CloneNotSupportedException e
) {
826 for (Extension removeObject
: removeListExtension
){
827 identifiableEntity2
.removeExtension(removeObject
);
828 getSession().delete(removeObject
);
832 session
.saveOrUpdate(cdmBase1
);
833 session
.saveOrUpdate(cdmBase2
);
837 private <T
extends CdmBase
> void testMergeValid(T cdmBase1
, T cdmBase2
)throws IllegalArgumentException
, NullPointerException
{
838 if (cdmBase1
== null || cdmBase2
== null){
839 throw new NullPointerException("Merge arguments must not be (null)");
841 cdmBase1
= (T
)HibernateProxyHelper
.deproxy(cdmBase1
);
842 cdmBase2
= (T
)HibernateProxyHelper
.deproxy(cdmBase2
);
844 if (cdmBase1
.getClass() != cdmBase2
.getClass()){
845 throw new IllegalArgumentException("Merge arguments must be of same type");
849 //TODO Move to test classes if still needed
850 private void test() {
851 SessionFactoryImpl factory
= (SessionFactoryImpl
)getSession().getSessionFactory();
852 Type propType
= factory
.getReferencedPropertyType(BotanicalName
.class.getCanonicalName(), "titleCache");
853 Map collMetadata
= factory
.getAllCollectionMetadata();
854 Object roles
= factory
.getCollectionRolesByEntityParticipant("eu.etaxonomy.cdm.model.name.BotanicalName");
855 CollectionPersister collPersister
;
857 collPersister
= factory
.getCollectionPersister(TaxonNameBase
.class.getCanonicalName()+".annotations");
858 } catch (MappingException e
) {
859 // TODO Auto-generated catch block
862 Statistics statistics
= factory
.getStatistics();
863 Map allClassMetadata
= factory
.getAllClassMetadata();
869 public <T
extends CdmBase
> T
find(Class
<T
> clazz
, int id
){
871 session
= getSession();
872 //session = getSession().getSessionFactory().getCurrentSession();
873 Object o
= session
.get(clazz
, id
);
878 public <T
extends IMatchable
> List
<T
> findMatching(T objectToMatch
,
879 IMatchStrategy matchStrategy
) throws MatchException
{
881 List
<T
> result
= new ArrayList
<T
>();
882 if(objectToMatch
== null){
885 if (matchStrategy
== null){
886 matchStrategy
= DefaultMatchStrategy
.NewInstance(objectToMatch
.getClass());
888 result
.addAll(findMatchingNullSafe(objectToMatch
, matchStrategy
));
890 } catch (IllegalArgumentException e
) {
891 throw new MatchException(e
);
892 } catch (IllegalAccessException e
) {
893 throw new MatchException(e
);
897 private <T
extends IMatchable
> List
<T
> findMatchingNullSafe(T objectToMatch
, IMatchStrategy matchStrategy
) throws IllegalArgumentException
, IllegalAccessException
, MatchException
{
898 List
<T
> result
= new ArrayList
<T
>();
899 Session session
= getSession();
900 Class
<?
> matchClass
= objectToMatch
.getClass();
901 ClassMetadata classMetaData
= session
.getSessionFactory().getClassMetadata(matchClass
.getCanonicalName());
902 Criteria criteria
= session
.createCriteria(matchClass
);
903 boolean noMatch
= makeCriteria(objectToMatch
, matchStrategy
, classMetaData
, criteria
);
904 logger
.debug(criteria
);
906 if (noMatch
== false){
907 List
<T
> matchCandidates
= criteria
.list();
908 matchCandidates
.remove(objectToMatch
);
909 for (T matchCandidate
: matchCandidates
){
910 if (matchStrategy
.invoke(objectToMatch
, matchCandidate
)){
911 result
.add(matchCandidate
);
913 logger
.warn("Match candidate did not match: " + matchCandidate
);
922 * @param objectToMatch
923 * @param matchStrategy
924 * @param classMetaData
927 * @throws IllegalAccessException
928 * @throws MatchException
930 private <T
> boolean makeCriteria(T objectToMatch
,
931 IMatchStrategy matchStrategy
, ClassMetadata classMetaData
,
932 Criteria criteria
) throws IllegalAccessException
, MatchException
{
933 Matching matching
= matchStrategy
.getMatching();
934 boolean noMatch
= false;
935 Map
<String
, List
<MatchMode
>> replaceMatchers
= new HashMap
<String
, List
<MatchMode
>>();
936 for (CacheMatcher cacheMatcher
: matching
.getCacheMatchers()){
937 boolean cacheProtected
= (Boolean
)cacheMatcher
.getProtectedField(matching
).get(objectToMatch
);
938 if (cacheProtected
== true){
939 String cacheValue
= (String
)cacheMatcher
.getField().get(objectToMatch
);
940 if (StringUtils
.isBlank(cacheValue
)){
941 return true; //no match
943 criteria
.add(Restrictions
.eq(cacheMatcher
.getPropertyName(), cacheValue
));
944 criteria
.add(Restrictions
.eq(cacheMatcher
.getProtectedPropertyName(), cacheProtected
));
946 List
<DoubleResult
<String
, MatchMode
>> replacementModes
= cacheMatcher
.getReplaceMatchModes(matching
);
947 for (DoubleResult
<String
, MatchMode
> replacementMode
: replacementModes
){
948 String propertyName
= replacementMode
.getFirstResult();
949 List
<MatchMode
> replaceMatcherList
= replaceMatchers
.get(propertyName
);
950 if (replaceMatcherList
== null){
951 replaceMatcherList
= new ArrayList
<MatchMode
>();
952 replaceMatchers
.put(propertyName
, replaceMatcherList
);
954 replaceMatcherList
.add(replacementMode
.getSecondResult());
960 for (FieldMatcher fieldMatcher
: matching
.getFieldMatchers(false)){
961 String propertyName
= fieldMatcher
.getPropertyName();
962 Type propertyType
= classMetaData
.getPropertyType(propertyName
);
963 Object value
= fieldMatcher
.getField().get(objectToMatch
);
964 List
<MatchMode
> matchModes
= new ArrayList
<MatchMode
>();
965 matchModes
.add(fieldMatcher
.getMatchMode());
966 if (replaceMatchers
.get(propertyName
) != null){
967 matchModes
.addAll(replaceMatchers
.get(propertyName
));
970 boolean isIgnore
= false;
971 for (MatchMode matchMode
: matchModes
){
972 isIgnore
|= matchMode
.isIgnore(value
);
975 if (propertyType
.isComponentType()){
976 matchComponentType(criteria
, fieldMatcher
, propertyName
, value
, matchModes
);
978 noMatch
= matchNonComponentType(criteria
, fieldMatcher
, propertyName
, value
, matchModes
, propertyType
);
990 * @param fieldMatcher
991 * @param propertyName
994 * @throws MatchException
995 * @throws IllegalAccessException
997 private void matchComponentType(Criteria criteria
,
998 FieldMatcher fieldMatcher
, String propertyName
, Object value
,
999 List
<MatchMode
> matchModes
) throws MatchException
, IllegalAccessException
{
1001 boolean requiresSecondNull
= requiresSecondNull(matchModes
, value
);
1002 if (requiresSecondNull
){
1003 criteria
.add(Restrictions
.isNull(propertyName
));
1006 logger
.warn("Component type not yet implemented for (null) value: " + propertyName
);
1007 throw new MatchException("Component type not yet fully implemented for (null) value. Property: " + propertyName
);
1010 Class
<?
> componentClass
= fieldMatcher
.getField().getType();
1011 Map
<String
, Field
> fields
= CdmUtils
.getAllFields(componentClass
, Object
.class, false, false, true, false);
1012 for (String fieldName
: fields
.keySet()){
1013 String restrictionPath
= propertyName
+"."+fieldName
;
1014 Object componentValue
= fields
.get(fieldName
).get(value
);
1015 //TODO diffentiate matchMode
1016 createCriterion(criteria
, restrictionPath
, componentValue
, matchModes
);
1021 private boolean matchNonComponentType(Criteria criteria
,
1022 FieldMatcher fieldMatcher
, String propertyName
, Object value
,
1023 List
<MatchMode
> matchModes
, Type propertyType
) throws HibernateException
, DataAccessException
, MatchException
, IllegalAccessException
{
1024 boolean noMatch
= false;
1025 if (isRequired(matchModes
) && value
== null){
1028 }else if (requiresSecondNull(matchModes
,value
)){
1029 criteria
.add(Restrictions
.isNull(propertyName
));
1031 if (isMatch(matchModes
)){
1032 if (propertyType
.isCollectionType()){
1033 //TODO collection not yet handled for match
1035 int joinType
= CriteriaSpecification
.INNER_JOIN
;
1036 if (! requiresSecondValue(matchModes
,value
)){
1037 joinType
= CriteriaSpecification
.LEFT_JOIN
;
1039 Criteria matchCriteria
= criteria
.createCriteria(propertyName
, joinType
).add(Restrictions
.isNotNull("id"));
1040 Class matchClass
= value
.getClass();
1041 if (IMatchable
.class.isAssignableFrom(matchClass
)){
1042 IMatchStrategy valueMatchStrategy
= DefaultMatchStrategy
.NewInstance((Class
<IMatchable
>)matchClass
);
1043 ClassMetadata valueClassMetaData
= getSession().getSessionFactory().getClassMetadata(matchClass
.getCanonicalName());;
1044 noMatch
= makeCriteria(value
, valueMatchStrategy
, valueClassMetaData
, matchCriteria
);
1046 logger
.error("Class to match (" + matchClass
+ ") is not of type IMatchable");
1047 throw new MatchException("Class to match (" + matchClass
+ ") is not of type IMatchable");
1050 }else if (isEqual(matchModes
)){
1051 createCriterion(criteria
, propertyName
, value
, matchModes
);
1053 logger
.warn("Unhandled match mode: " + matchModes
+ ", value: " + (value
==null?
"null":value
));
1061 * @param propertyName
1064 * @throws MatchException
1066 private void createCriterion(Criteria criteria
, String propertyName
,
1067 Object value
, List
<MatchMode
> matchModes
) throws MatchException
{
1068 Criterion finalRestriction
= null;
1069 Criterion equalRestriction
= Restrictions
.eq(propertyName
, value
);
1070 Criterion nullRestriction
= Restrictions
.isNull(propertyName
);
1071 if (this.requiresSecondValue(matchModes
, value
)){
1072 finalRestriction
= equalRestriction
;
1073 }else if (requiresSecondNull(matchModes
, value
) ){
1074 finalRestriction
= nullRestriction
;
1076 finalRestriction
= Restrictions
.or(equalRestriction
, nullRestriction
);
1078 //return finalRestriction;
1079 criteria
.add(finalRestriction
);
1086 * @throws MatchException
1088 private boolean requiresSecondNull(List
<MatchMode
> matchModes
, Object value
) throws MatchException
{
1089 boolean result
= true;
1090 for (MatchMode matchMode
: matchModes
){
1091 result
&= matchMode
.requiresSecondNull(value
);
1100 * @throws MatchException
1102 private boolean requiresSecondValue(List
<MatchMode
> matchModes
, Object value
) throws MatchException
{
1103 boolean result
= true;
1104 for (MatchMode matchMode
: matchModes
){
1105 result
&= matchMode
.requiresSecondValue(value
);
1114 * @throws MatchException
1116 private boolean isRequired(List
<MatchMode
> matchModes
) throws MatchException
{
1117 boolean result
= true;
1118 for (MatchMode matchMode
: matchModes
){
1119 result
&= matchMode
.isRequired();
1125 * Returns true if at least one match mode is of typ MATCH_XXX
1129 * @throws MatchException
1131 private boolean isMatch(List
<MatchMode
> matchModes
) throws MatchException
{
1132 boolean result
= false;
1133 for (MatchMode matchMode
: matchModes
){
1134 result
|= matchMode
.isMatch();
1140 * Returns true if at least one match mode is of typ EQUAL_XXX
1144 * @throws MatchException
1146 private boolean isEqual(List
<MatchMode
> matchModes
) throws MatchException
{
1147 boolean result
= false;
1148 for (MatchMode matchMode
: matchModes
){
1149 result
|= matchMode
.isEqual();
1155 * @see eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao#saveMetaData(eu.etaxonomy.cdm.model.common.CdmMetaData)
1157 public void saveMetaData(CdmMetaData cdmMetaData
) {
1158 getSession().saveOrUpdate(cdmMetaData
);
1162 * @see eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao#getMetaData()
1164 public List
<CdmMetaData
> getMetaData() {
1165 Session session
= getSession();
1166 Criteria crit
= session
.createCriteria(CdmMetaData
.class);
1167 List
<CdmMetaData
> results
= crit
.list();
1172 public PersistentCollection
initializeCollection(PersistentCollection col
) {
1173 Session session
= getSession();
1174 col
.setCurrentSession((SessionImplementor
) session
);
1176 if(!((SessionImplementor
)session
).getPersistenceContext().getCollectionEntries().containsKey(col
)) {
1177 ((SessionImplementor
)session
).getPersistenceContext().addUninitializedDetachedCollection(
1178 ((SessionImplementor
)session
).getFactory().getCollectionPersister( col
.getRole() ),col
);
1180 col
.forceInitialization();
1181 logger
.debug("initialising persistent collection with with role : " + col
.getRole() + " and key : " + col
.getKey());
1186 public boolean isEmpty(PersistentCollection col
) {
1187 return initializeCollection(col
).empty();
1191 public int size(PersistentCollection col
) {
1192 logger
.debug("remote size() - for role : " + col
.getRole() + " and key : " + col
.getKey());
1193 initializeCollection(col
);
1194 SessionImplementor session
= (SessionImplementor
)getSession();
1195 CollectionEntry entry
= session
.getPersistenceContext().getCollectionEntry(col
);
1197 if ( entry
!= null ) {
1199 CollectionPersister persister
= entry
.getLoadedPersister();
1200 return persister
.getSize( entry
.getLoadedKey(), session
);
1206 public Object
get(PersistentCollection col
, int index
) {
1207 logger
.debug("remote get() - for role : " + col
.getRole() + " and key : " + col
.getKey());
1208 initializeCollection(col
);
1209 SessionImplementor session
= (SessionImplementor
)getSession();
1210 CollectionEntry entry
= session
.getPersistenceContext().getCollectionEntry(col
);
1212 if ( entry
!= null ) {
1214 CollectionPersister persister
= entry
.getLoadedPersister();
1215 return persister
.getElementByIndex(entry
.getLoadedKey(), index
, session
, col
);
1218 //FIXME:Remoting Should we not be throwing an exception here ?
1223 public boolean contains(PersistentCollection col
, Object element
) {
1224 logger
.debug("remote contains() - for role : " + col
.getRole() + " and key : " + col
.getKey());
1225 initializeCollection(col
);
1226 SessionImplementor session
= (SessionImplementor
)getSession();
1227 CollectionEntry entry
= session
.getPersistenceContext().getCollectionEntry(col
);
1229 if ( entry
!= null ) {
1231 CollectionPersister persister
= entry
.getLoadedPersister();
1232 return persister
.elementExists(entry
.getLoadedKey(), element
, session
);
1234 //FIXME:Remoting Should we not be throwing an exception here ?
1239 public boolean containsKey(PersistentCollection col
, Object key
) {
1240 logger
.debug("remote containsKey() - for role : " + col
.getRole() + " and key : " + col
.getKey());
1241 initializeCollection(col
);
1242 SessionImplementor session
= (SessionImplementor
)getSession();
1243 CollectionEntry entry
= session
.getPersistenceContext().getCollectionEntry(col
);
1245 if ( entry
!= null ) {
1247 CollectionPersister persister
= entry
.getLoadedPersister();
1248 return persister
.indexExists(entry
.getLoadedKey(), key
, session
);
1250 //FIXME:Remoting Should we not be throwing an exception here ?
1256 public boolean containsValue(PersistentCollection col
, Object element
) {
1257 return contains(col
, element
);