KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > cfg > annotations > CollectionBinder


1 package org.hibernate.cfg.annotations;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.Comparator JavaDoc;
5 import java.util.HashMap JavaDoc;
6 import java.util.Iterator JavaDoc;
7 import java.util.Map JavaDoc;
8 import java.util.StringTokenizer JavaDoc;
9 import java.util.List JavaDoc;
10 import javax.persistence.FetchType;
11 import javax.persistence.MapKey;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.hibernate.AnnotationException;
16 import org.hibernate.AssertionFailure;
17 import org.hibernate.FetchMode;
18 import org.hibernate.MappingException;
19 import org.hibernate.annotations.BatchSize;
20 import org.hibernate.annotations.Cache;
21 import org.hibernate.annotations.OrderBy;
22 import org.hibernate.annotations.Sort;
23 import org.hibernate.annotations.SortType;
24 import org.hibernate.annotations.Where;
25 import org.hibernate.cfg.AnnotationBinder;
26 import org.hibernate.cfg.Ejb3JoinColumn;
27 import org.hibernate.cfg.ExtendedMappings;
28 import org.hibernate.cfg.IndexColumn;
29 import org.hibernate.cfg.PropertyHolder;
30 import org.hibernate.cfg.SecondPass;
31 import org.hibernate.cfg.PropertyInferredData;
32 import org.hibernate.cfg.BinderHelper;
33 import org.hibernate.mapping.Backref;
34 import org.hibernate.mapping.Collection;
35 import org.hibernate.mapping.DependantValue;
36 import org.hibernate.mapping.Join;
37 import org.hibernate.mapping.KeyValue;
38 import org.hibernate.mapping.ManyToOne;
39 import org.hibernate.mapping.OneToMany;
40 import org.hibernate.mapping.PersistentClass;
41 import org.hibernate.mapping.Property;
42 import org.hibernate.mapping.SimpleValue;
43 import org.hibernate.mapping.Table;
44 import org.hibernate.mapping.Column;
45 import org.hibernate.util.StringHelper;
46
47 /**
48  * Collection binder
49  *
50  * @author inger
51  * @author emmanuel
52  */

53 public abstract class CollectionBinder {
54
55     private static final Log log = LogFactory.getLog(CollectionBinder.class);
56
57     protected Collection collection;
58     protected String JavaDoc propertyName;
59     FetchMode fetchMode;
60     PropertyHolder propertyHolder;
61     int batchSize;
62     String JavaDoc where;
63     private String JavaDoc mappedBy;
64     private Table table;
65     private Class JavaDoc collectionType;
66     private String JavaDoc targetEntity;
67     private ExtendedMappings mappings;
68     private boolean unique;
69     private Ejb3JoinColumn[] inverseJoinColumns;
70     private String JavaDoc cascadeStrategy;
71     String JavaDoc cacheConcurrencyStrategy;
72     Map JavaDoc<String JavaDoc, String JavaDoc> filters = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
73     String JavaDoc cacheRegionName;
74     private boolean oneToMany;
75     protected IndexColumn indexColumn;
76     private String JavaDoc orderBy;
77     protected String JavaDoc hqlOrderBy;
78     private boolean isSorted;
79     private Class JavaDoc comparator;
80     private boolean hasToBeSorted;
81     protected boolean cascadeDeleteEnabled;
82     protected String JavaDoc mapKeyPropertyName;
83     private boolean insertable = true;
84     private boolean updatable = true;
85
86     public void setUpdatable(boolean updatable) {
87         this.updatable = updatable;
88     }
89
90     public void setInsertable(boolean insertable) {
91         this.insertable = insertable;
92     }
93
94
95     public void setCascadeStrategy(String JavaDoc cascadeStrategy) {
96         this.cascadeStrategy = cascadeStrategy;
97     }
98
99     public void setPropertyAccessorName(String JavaDoc propertyAccessorName) {
100         this.propertyAccessorName = propertyAccessorName;
101     }
102
103     private String JavaDoc propertyAccessorName;
104
105     public void setUnique(boolean unique) {
106         this.unique = unique;
107     }
108
109     public void setInverseJoinColumns(Ejb3JoinColumn[] inverseJoinColumns) {
110         this.inverseJoinColumns = inverseJoinColumns;
111     }
112
113     public void setJoinColumns(Ejb3JoinColumn[] joinColumns) {
114         this.joinColumns = joinColumns;
115     }
116
117     private Ejb3JoinColumn[] joinColumns;
118
119     public void setPropertyHolder(PropertyHolder propertyHolder) {
120         this.propertyHolder = propertyHolder;
121     }
122
123     public void setBatchSize(BatchSize batchSize) {
124         this.batchSize = batchSize == null ? -1 : batchSize.size();
125     }
126
127     public void setEjb3OrderBy(javax.persistence.OrderBy orderByAnn) {
128         if (orderByAnn != null) {
129             hqlOrderBy = orderByAnn.value();
130         }
131     }
132
133     public void setSqlOrderBy(OrderBy orderByAnn) {
134         if (orderByAnn != null) {
135             if ( ! AnnotationBinder.isDefault( orderByAnn.clause() ) ) orderBy = orderByAnn.clause();
136         }
137     }
138
139     public void setSort(Sort sortAnn) {
140         if (sortAnn != null) {
141             isSorted = ! SortType.UNSORTED.equals( sortAnn.type() );
142             if (isSorted && SortType.COMPARATOR.equals( sortAnn.type() ) ) {
143                 comparator = sortAnn.comparator();
144             }
145         }
146     }
147
148     /** collection binder factory */
149     public static CollectionBinder getCollectionBinder(String JavaDoc entityName, PropertyInferredData inferredData,
150             boolean isIndexed) {
151         CollectionBinder binder = null;
152         Class JavaDoc returnedClass = inferredData.getReturnedClassOrElement();
153         if ( inferredData.isArray() ) {
154             binder = new ArrayBinder();
155         }
156         else if ( java.util.Set JavaDoc.class.equals(returnedClass) ) {
157             binder = new SetBinder();
158         }
159         else if ( java.util.SortedSet JavaDoc.class.equals(returnedClass) ) {
160             binder = new SetBinder(true);
161         }
162         else if ( java.util.Map JavaDoc.class.equals(returnedClass) ) {
163             binder = new MapBinder();
164         }
165         else if ( java.util.Collection JavaDoc.class.equals(returnedClass)) {
166             binder = new BagBinder();
167         }
168         else if ( java.util.List JavaDoc.class.equals(returnedClass) ) {
169             if (isIndexed == true) {
170                 binder = new ListBinder();
171             }
172             else {
173                 binder = new BagBinder();
174             }
175         }
176         else {
177             throw new AnnotationException(returnedClass.getName() + " collection not yet supported: "
178                     + entityName + inferredData.getPropertyName() );
179         }
180         return binder;
181     }
182
183     protected CollectionBinder() {}
184
185     protected CollectionBinder(boolean sorted) {
186         this.hasToBeSorted = sorted;
187     }
188
189     public void setMappedBy(String JavaDoc mappedBy) {
190         this.mappedBy = mappedBy;
191     }
192
193     public void setTable(Table table) {
194         this.table = table;
195     }
196
197     public void setCollectionType(Class JavaDoc collectionType) {
198         this.collectionType = collectionType;
199     }
200
201     public void setTargetEntity(Class JavaDoc targetEntity) {
202         if ( AnnotationBinder.isDefault(targetEntity) ) {
203             this.targetEntity = AnnotationBinder.ANNOTATION_STRING_DEFAULT;
204         }
205         else {
206             this.targetEntity = targetEntity.getName();
207         }
208     }
209
210     public void setMappings(ExtendedMappings mappings) {
211         this.mappings = mappings;
212     }
213
214     protected abstract Collection createCollection(PersistentClass persistentClass);
215
216     public Collection getCollection() {
217         return collection;
218     }
219
220     public void setPropertyName(String JavaDoc propertyName) {
221         this.propertyName = propertyName;
222     }
223
224     public void bind() {
225         if ( log.isDebugEnabled() ) {
226             if (! oneToMany) {
227                 if ( unique == false ) {
228                     log.debug("Binding as ManyToMany: " + propertyHolder.getEntityName() + "." + propertyName);
229                 }
230                 else {
231                     log.debug("Binding a OneToMany: " + propertyHolder.getEntityName() + "." + propertyName + " through an association table");
232                 }
233             } else {
234                 log.debug("Binding a OneToMany: " + propertyHolder.getEntityName() + "." + propertyName + " through a foreign key");
235             }
236         }
237         this.collection = createCollection( propertyHolder.getPersistentClass() );
238         log.debug( "Collection role: " + StringHelper.qualify( propertyHolder.getPath(), propertyName) );
239         collection.setRole( StringHelper.qualify( propertyHolder.getPath(), propertyName) );
240
241         //set laziness
242
collection.setFetchMode(fetchMode);
243         collection.setLazy(fetchMode == FetchMode.SELECT);
244         collection.setBatchSize(batchSize);
245         if (orderBy != null && hqlOrderBy != null)
246             throw new AnnotationException("Cannot use sql order by clause in conjunction of EJB3 order by clause: " + safeCollectionRole() );
247         if (orderBy != null) collection.setOrderBy(orderBy);
248         if (isSorted) {
249             collection.setSorted(true);
250             if (comparator != null) {
251                 try {
252                     collection.setComparator( (Comparator JavaDoc) comparator.newInstance() );
253                 }
254                 catch (Exception JavaDoc e) {
255                     throw new AnnotationException( "Could not instantiate comparator class: "
256                         + comparator.getName() + "(" + safeCollectionRole() + ")" );
257                 }
258             }
259         }
260         else {
261             if (hasToBeSorted) throw new AnnotationException("A sorted collection has to define @Sort: "
262                      + safeCollectionRole() );
263         }
264
265         if ( StringHelper.isNotEmpty( cacheConcurrencyStrategy ) ) {
266             collection.setCacheConcurrencyStrategy(cacheConcurrencyStrategy);
267             collection.setCacheRegionName(cacheRegionName);
268         }
269         Iterator JavaDoc<Map.Entry JavaDoc<String JavaDoc, String JavaDoc>> iter = filters.entrySet().iterator();
270         if ( StringHelper.isNotEmpty(where) ) collection.setWhere(where);
271         while (iter.hasNext()) {
272             Map.Entry JavaDoc<String JavaDoc, String JavaDoc> filter = iter.next();
273             collection.addFilter(filter.getKey(), filter.getValue());
274         }
275         boolean isMappedBy = ! AnnotationBinder.isDefault(mappedBy);
276         collection.setInverse( isMappedBy );
277         collection.setCollectionTable(table);
278         String JavaDoc collType = getCollectionType();
279         if (oneToMany) {
280             org.hibernate.mapping.OneToMany oneToMany = new org.hibernate.mapping.OneToMany( collection.getOwner() );
281             collection.setElement(oneToMany);
282             oneToMany.setReferencedEntityName( collType );
283         }
284         else {
285             //many to many may need some second pass informations
286
if ( isMappedBy ) {
287                 mappings.addMappedBy( collType, mappedBy, propertyName );
288             }
289         }
290         mappings.addSecondPass(
291                 getSecondPass(mappings, joinColumns, inverseJoinColumns, collType, fetchMode, unique),
292                 ! isMappedBy
293         );
294         mappings.addCollection(collection);
295         PropertyBinder binder = new PropertyBinder();
296         binder.setName(propertyName);
297         binder.setValue(collection);
298         binder.setCascade(cascadeStrategy);
299         binder.setPropertyAccessorName(propertyAccessorName);
300         binder.setInsertable( insertable );
301         binder.setUpdatable( updatable );
302         Property prop = binder.make();
303         //we don't care about the join stuffs because the column is on the association table.
304
propertyHolder.addProperty(prop);
305     }
306
307     private String JavaDoc getCollectionType() {
308         if ( AnnotationBinder.isDefault(targetEntity) ) {
309             if (collectionType != null) {
310                 return collectionType.getName();
311             }
312             else {
313                 String JavaDoc errorMsg = "Collection has neither generic type or OneToMany.targetEntity() defined: "
314                         + safeCollectionRole();
315                 throw new AnnotationException(errorMsg);
316             }
317         }
318         else {
319             return targetEntity;
320         }
321     }
322
323     public SecondPass getSecondPass(final ExtendedMappings mappings,
324                                               final Ejb3JoinColumn[] keyColumns,
325                                               final Ejb3JoinColumn[] inverseColumns,
326                                               final String JavaDoc collType,
327                                               final FetchMode fetchMode,
328                                               final boolean unique) {
329         if (inverseColumns != null) {
330             return new SecondPass(mappings, collection) {
331                 public void secondPass(Map JavaDoc persistentClasses, Map JavaDoc inheritedMetas)
332                         throws MappingException {
333                     bindManyToManySecondPass(
334                             getCollection(),
335                             persistentClasses,
336                             keyColumns,
337                             inverseColumns,
338                             collType,
339                             fetchMode,
340                             unique,
341                             cascadeDeleteEnabled, (ExtendedMappings) getMappings()
342                     );
343                 }
344             };
345         }
346         else {
347             return new SecondPass(mappings, collection) {
348                 public void secondPass(Map JavaDoc persistentClasses, Map JavaDoc inheritedMetas)
349                         throws MappingException {
350                     bindCollectionSecondPass(
351                             getCollection(),
352                             persistentClasses,
353                             keyColumns,
354                             cascadeDeleteEnabled,
355                             hqlOrderBy,
356                             (ExtendedMappings) getMappings()
357                     );
358                 }
359             };
360         }
361     }
362
363     public void setCache(Cache cacheAnn) {
364         if (cacheAnn != null) {
365             cacheRegionName = AnnotationBinder.isDefault( cacheAnn.region() ) ? null : cacheAnn.region();
366             cacheConcurrencyStrategy = EntityBinder.getCacheConcurrencyStrategy( cacheAnn.usage() );
367         }
368         else {
369             cacheConcurrencyStrategy = null;
370             cacheRegionName = null;
371         }
372     }
373
374     public void setFetchType(FetchType fetch) {
375         if (fetch == FetchType.EAGER) {
376             fetchMode = FetchMode.JOIN;
377         }
378         else {
379             fetchMode = FetchMode.SELECT;
380         }
381     }
382
383     public void addFilter(String JavaDoc name, String JavaDoc condition) {
384         filters.put(name, condition);
385     }
386
387     public void setWhere(Where whereAnn) {
388         if (whereAnn != null) {
389             where = whereAnn.clause();
390         }
391     }
392
393     public void setOneToMany(boolean oneToMany) {
394         this.oneToMany = oneToMany;
395     }
396
397     public void setIndexColumn(IndexColumn indexColumn) {
398         this.indexColumn = indexColumn;
399     }
400
401     public void setMapKey(MapKey key) {
402         if (key != null) {
403             mapKeyPropertyName = key.name();
404         }
405     }
406
407     protected static void bindCollectionSecondPass(
408             Collection collValue, Map JavaDoc persistentClasses, Ejb3JoinColumn[] columns, boolean cascadeDeleteEnabled,
409             String JavaDoc hqlOrderBy, ExtendedMappings mappings
410             ) throws MappingException {
411         if ( collValue.isOneToMany() ) {
412             org.hibernate.mapping.OneToMany oneToMany =
413                 (org.hibernate.mapping.OneToMany) collValue.getElement();
414             String JavaDoc assocClass = oneToMany.getReferencedEntityName();
415             PersistentClass associatedClass = (PersistentClass) persistentClasses.get(assocClass);
416             String JavaDoc orderBy = buildOrderByClauseFromHql(hqlOrderBy, associatedClass, collValue.getRole() );
417             if (orderBy != null) collValue.setOrderBy(orderBy);
418             if (mappings == null) {
419                 throw new AssertionFailure("CollectionSecondPass for oneToMany should not be called with null mappings");
420             }
421             Map JavaDoc<String JavaDoc, Join> joins = mappings.getJoins(assocClass);
422             if (associatedClass==null) throw new MappingException(
423                 "Association references unmapped class: " + assocClass
424             );
425             oneToMany.setAssociatedClass(associatedClass);
426             //FIXME: find the appropriate table between second and primary
427
for (Ejb3JoinColumn column : columns) {
428                 column.setPersistentClass(associatedClass);
429                 column.setJoins(joins);
430                 collValue.setCollectionTable( column.getTable() );
431             }
432             log.info("Mapping collection: " + collValue.getRole() + " -> " + collValue.getCollectionTable().getName() );
433         }
434
435         bindCollectionSecondPass(collValue, null, columns, cascadeDeleteEnabled, mappings );
436         if ( collValue.isOneToMany()
437             && !collValue.isInverse()
438             && !collValue.getKey().isNullable() ) {
439             // for non-inverse one-to-many, with a not-null fk, add a backref!
440
String JavaDoc entityName = ( (OneToMany) collValue.getElement() ).getReferencedEntityName();
441             PersistentClass referenced = mappings.getClass( entityName );
442             Backref prop = new Backref();
443             prop.setName( '_' + columns[0].getPropertyName() + "Backref" );
444             prop.setUpdateable( false );
445             prop.setSelectable( false );
446             prop.setCollectionRole( collValue.getRole() );
447             prop.setEntityName( collValue.getOwner().getEntityName() );
448             prop.setValue( collValue.getKey() );
449             referenced.addProperty( prop );
450         }
451     }
452
453     private static String JavaDoc buildOrderByClauseFromHql(String JavaDoc hqlOrderBy, PersistentClass associatedClass, String JavaDoc role) {
454         String JavaDoc orderByString = null;
455         if (hqlOrderBy != null) {
456             List JavaDoc<String JavaDoc> properties = new ArrayList JavaDoc<String JavaDoc>();
457             List JavaDoc<String JavaDoc> ordering = new ArrayList JavaDoc<String JavaDoc>();
458             StringBuffer JavaDoc orderByBuffer = new StringBuffer JavaDoc();
459             if ( "".equals( hqlOrderBy ) ) {
460                 //order by id
461
Iterator JavaDoc it = associatedClass.getIdentifier().getColumnIterator();
462                 while( it.hasNext() ) {
463                     Column col = (Column) it.next();
464                     orderByBuffer.append( col.getName() ).append(" asc").append(", ");
465                 }
466             }
467             else {
468                 StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(hqlOrderBy, " ,", false);
469                 String JavaDoc currentOrdering = null;
470                 //FIXME make this code decent
471
while( st.hasMoreTokens() ) {
472                     String JavaDoc token = st.nextToken();
473                     if ( isNonPropertyToken(token) ) {
474                         if (currentOrdering != null)
475                             throw new AnnotationException("Error while parsing HQL orderBy clause: " + hqlOrderBy
476                                 + " (" + role + ")");
477                         currentOrdering = token;
478                     }
479                     else {
480                         //Add ordering of the previous
481
if (currentOrdering == null) {
482                             //default ordering
483
ordering.add("asc");
484                         }
485                         else {
486                             ordering.add(currentOrdering);
487                             currentOrdering = null;
488                         }
489                         properties.add(token);
490                     }
491                 }
492                 ordering.remove(0); //first one is the algorithm starter
493
// add last one ordering
494
if (currentOrdering == null) {
495                     //default ordering
496
ordering.add("asc");
497                 }
498                 else {
499                     ordering.add(currentOrdering);
500                     currentOrdering = null;
501                 }
502                 int index = 0;
503
504                 for (String JavaDoc property : properties) {
505                     Property p = BinderHelper.findPropertyByName(associatedClass, property );
506                     if (p == null) {
507                         throw new AnnotationException("property from @OrderBy clause not found: "
508                             + associatedClass.getEntityName() + "." + property);
509                     }
510
511                     Iterator JavaDoc propertyColumns = p.getColumnIterator();
512                     while ( propertyColumns.hasNext() ) {
513                         Column column = (Column) propertyColumns.next();
514                         orderByBuffer.append( column.getName() ).append(" ").append( ordering.get(index) ).append(", ");
515                     }
516                     index++;
517                 }
518             }
519             orderByString = orderByBuffer.substring(0, orderByBuffer.length() - 2);
520         }
521         return orderByString;
522     }
523
524     private static boolean isNonPropertyToken(String JavaDoc token) {
525         if ( " ".equals(token) ) return true;
526         if ( ",".equals(token) ) return true;
527         if ( token.equalsIgnoreCase("desc") ) return true;
528         if ( token.equalsIgnoreCase("asc") ) return true;
529         return false;
530     }
531
532     private static SimpleValue buildCollectionKey(
533             Collection collValue, Ejb3JoinColumn[] joinColumns, boolean cascadeDeleteEnabled,
534             ExtendedMappings mappings
535             ) {
536         //binding key reference using column
537
KeyValue keyVal;
538         //give a chance to override the referenced property name
539
//has to do that here because the referencedProperty creation happens in a FKSecondPass for Many to one yuk!
540
if (joinColumns.length > 0 && StringHelper.isNotEmpty( joinColumns[0].getMappedBy() ) ) {
541             String JavaDoc propRef = mappings.getPropertyReferencedAssociation(
542                     joinColumns[0].getPropertyHolder().getEntityName(),
543                     joinColumns[0].getMappedBy()
544             );
545             if (propRef != null) {
546                 collValue.setReferencedPropertyName( propRef );
547                 mappings.addPropertyReference( collValue.getOwnerEntityName(), propRef );
548             }
549         }
550         String JavaDoc propRef = collValue.getReferencedPropertyName();
551         if (propRef==null) {
552             keyVal = collValue.getOwner().getIdentifier();
553         }
554         else {
555             keyVal = (KeyValue) collValue.getOwner()
556                 .getProperty(propRef)
557                 .getValue();
558         }
559         DependantValue key = new DependantValue( collValue.getCollectionTable(), keyVal );
560         key.setTypeName(null);
561         Ejb3JoinColumn.checkPropertyConsistency( joinColumns, collValue.getOwnerEntityName() );
562         key.setNullable( joinColumns.length == 0 ? true : joinColumns[0].isNullable() );
563         key.setUpdateable( joinColumns.length == 0 ? true : joinColumns[0].isUpdatable() );
564         key.setCascadeDeleteEnabled(cascadeDeleteEnabled);
565         collValue.setKey(key);
566         return key;
567     }
568
569     protected static void bindManyToManySecondPass(
570             Collection collValue,
571             Map JavaDoc persistentClasses,
572             Ejb3JoinColumn[] joinColumns,
573             Ejb3JoinColumn[] inverseJoinColumns,
574             String JavaDoc collType,
575             FetchMode fetchMode,
576             boolean unique,
577             boolean cascadeDeleteEnabled, ExtendedMappings mappings
578             ) throws MappingException {
579
580         PersistentClass collectionEntity = (PersistentClass) persistentClasses.get(collType);
581         if (collectionEntity == null) {
582             throw new MappingException(
583                 "Association references unmapped class: " + collType
584             );
585         }
586         boolean mappedBy = ! AnnotationBinder.isDefault(joinColumns[0].getMappedBy() );
587         if ( mappedBy ) {
588             Property otherSideProperty;
589             try {
590                 otherSideProperty = collectionEntity.getProperty( joinColumns[0].getMappedBy() );
591             } catch (MappingException e) {
592                 throw new AnnotationException("mappedBy reference an unknown property: " + collType + "." + joinColumns[0].getMappedBy() );
593             }
594             Table table = ( (Collection) otherSideProperty.getValue() ).getCollectionTable();
595             collValue.setCollectionTable(table);
596             for (Ejb3JoinColumn column : joinColumns) {
597                 column.setDefaultColumnHeader( joinColumns[0].getMappedBy() );
598             }
599         }
600         else {
601             //TODO: only for implicit columns?
602
for (Ejb3JoinColumn column : joinColumns) {
603                 String JavaDoc header = mappings.getFromMappedBy( collValue.getOwnerEntityName() , column.getPropertyName() );
604                 header = (header == null) ? collValue.getOwner().getTable().getName() : header;
605                 column.setDefaultColumnHeader( header );
606             }
607             if ( collValue.getCollectionTable() == null ) {
608                 //default value
609
String JavaDoc tableName = collValue.getOwner().getTable().getName()
610                         + "_"
611                         + collectionEntity.getTable().getName();
612                 Table table = TableBinder.fillTable("", "", tableName, false, new ArrayList JavaDoc(), null, null, mappings);
613                 collValue.setCollectionTable(table);
614             }
615         }
616         bindCollectionSecondPass(collValue, collectionEntity, joinColumns, cascadeDeleteEnabled, mappings );
617
618         ManyToOne element =
619             new ManyToOne( collValue.getCollectionTable() );
620         collValue.setElement(element);
621         element.setReferencedEntityName(collType);
622         element.setFetchMode(fetchMode);
623         element.setLazy(fetchMode!=FetchMode.JOIN);
624
625         //for now it can't happen, but sometime soon...
626
if ( ( collValue.getFilterMap().size() != 0 || StringHelper.isNotEmpty( collValue.getWhere() ) ) &&
627             collValue.getFetchMode() == FetchMode.JOIN &&
628             collValue.getElement().getFetchMode() != FetchMode.JOIN ) {
629             throw new MappingException("@ManyToMany defining filter or where without join fetching "
630                 + "not valid within collection using join fetching[" + collValue.getRole() + "]");
631         }
632
633         //FIXME: do optional = false
634
if (collectionEntity==null) throw new MappingException(
635             "Association references unmapped class: " + collType
636         );
637         TableBinder.bindManytoManyInverseFk(collectionEntity, inverseJoinColumns, element, unique, mappings );
638
639     }
640
641     private static void bindCollectionSecondPass(
642             Collection collValue, PersistentClass collectionEntity, Ejb3JoinColumn[] joinColumns, boolean cascadeDeleteEnabled,
643             ExtendedMappings mappings
644             ) {
645         BinderHelper.createSyntheticPropertyReference( joinColumns, collValue.getOwner(), collValue, mappings );
646         SimpleValue key = buildCollectionKey(collValue, joinColumns, cascadeDeleteEnabled, mappings );
647         TableBinder.bindFk(collValue.getOwner(), collectionEntity, joinColumns, key, false );
648     }
649
650     public void setCascadeDeleteEnabled(boolean onDeleteCascade) {
651         this.cascadeDeleteEnabled = onDeleteCascade;
652     }
653
654     private String JavaDoc safeCollectionRole() {
655         if (propertyHolder != null) {
656             return propertyHolder.getEntityName() + "." + propertyName;
657         }
658         else {
659             return "";
660         }
661     }
662
663
664 }
Popular Tags