1 package org.hibernate.mapping; 3 4 import java.util.Comparator ; 5 import java.util.HashMap ; 6 import java.util.HashSet ; 7 import java.util.Iterator ; 8 9 import org.hibernate.FetchMode; 10 import org.hibernate.MappingException; 11 import org.hibernate.engine.Mapping; 12 import org.hibernate.type.CollectionType; 13 import org.hibernate.type.Type; 14 import org.hibernate.type.TypeFactory; 15 import org.hibernate.util.ArrayHelper; 16 import org.hibernate.util.EmptyIterator; 17 18 23 public abstract class Collection implements Fetchable, Value, Filterable { 24 25 public static final String DEFAULT_ELEMENT_COLUMN_NAME = "elt"; 26 public static final String DEFAULT_KEY_COLUMN_NAME = "id"; 27 28 private KeyValue key; 29 private Value element; 30 private Table collectionTable; 31 private String role; 32 private boolean lazy; 33 private boolean inverse; 34 private boolean mutable = true; 35 private boolean subselectLoadable; 36 private String cacheConcurrencyStrategy; 37 private String cacheRegionName; 38 private String orderBy; 39 private String where; 40 private String manyToManyWhere; 41 private PersistentClass owner; 42 private String referencedPropertyName; 43 private String nodeName; 44 private String elementNodeName; 45 private boolean sorted; 46 private Comparator comparator; 47 private boolean orphanDelete; 48 private int batchSize = -1; 49 private FetchMode fetchMode; 50 private boolean embedded = true; 51 private boolean optimisticLocked = true; 52 private Class collectionPersisterClass; 53 private String typeName; 54 private final java.util.Map filters = new HashMap (); 55 private final java.util.Map manyToManyFilters = new HashMap (); 56 private final java.util.Set synchronizedTables = new HashSet (); 57 58 private String customSQLInsert; 59 private String customSQLUpdate; 60 private String customSQLDelete; 61 private String customSQLDeleteAll; 62 private boolean customInsertCallable; 63 private boolean customUpdateCallable; 64 private boolean customDeleteCallable; 65 private boolean customDeleteAllCallable; 66 67 private String loaderName; 68 69 protected Collection(PersistentClass owner) { 70 this.owner = owner; 71 } 72 73 public boolean isSet() { 74 return false; 75 } 76 77 public KeyValue getKey() { 78 return key; 79 } 80 81 public Value getElement() { 82 return element; 83 } 84 85 public boolean isIndexed() { 86 return false; 87 } 88 89 public Table getCollectionTable() { 90 return collectionTable; 91 } 92 93 public void setCollectionTable(Table table) { 94 this.collectionTable = table; 95 } 96 97 public boolean isSorted() { 98 return sorted; 99 } 100 101 public Comparator getComparator() { 102 return comparator; 103 } 104 105 public boolean isLazy() { 106 return lazy; 107 } 108 109 public void setLazy(boolean lazy) { 110 this.lazy = lazy; 111 } 112 113 public String getRole() { 114 return role; 115 } 116 117 public abstract CollectionType getDefaultCollectionType() throws MappingException; 118 119 public boolean isPrimitiveArray() { 120 return false; 121 } 122 123 public boolean isArray() { 124 return false; 125 } 126 127 public boolean hasFormula() { 128 return false; 129 } 130 131 public boolean isOneToMany() { 132 return element instanceof OneToMany; 133 } 134 135 public boolean isInverse() { 136 return inverse; 137 } 138 139 public String getOwnerEntityName() { 140 return owner.getEntityName(); 141 } 142 143 public String getOrderBy() { 144 return orderBy; 145 } 146 147 public void setComparator(Comparator comparator) { 148 this.comparator = comparator; 149 } 150 151 public void setElement(Value element) { 152 this.element = element; 153 } 154 155 public void setKey(KeyValue key) { 156 this.key = key; 157 } 158 159 public void setOrderBy(String orderBy) { 160 this.orderBy = orderBy; 161 } 162 163 public void setRole(String role) { 164 this.role = role==null ? null : role.intern(); 165 } 166 167 public void setSorted(boolean sorted) { 168 this.sorted = sorted; 169 } 170 171 public void setInverse(boolean inverse) { 172 this.inverse = inverse; 173 } 174 175 public PersistentClass getOwner() { 176 return owner; 177 } 178 179 public void setOwner(PersistentClass owner) { 180 this.owner = owner; 181 } 182 183 public String getWhere() { 184 return where; 185 } 186 187 public void setWhere(String where) { 188 this.where = where; 189 } 190 191 public String getManyToManyWhere() { 192 return manyToManyWhere; 193 } 194 195 public void setManyToManyWhere(String manyToManyWhere) { 196 this.manyToManyWhere = manyToManyWhere; 197 } 198 199 public boolean isIdentified() { 200 return false; 201 } 202 203 public boolean hasOrphanDelete() { 204 return orphanDelete; 205 } 206 207 public void setOrphanDelete(boolean orphanDelete) { 208 this.orphanDelete = orphanDelete; 209 } 210 211 public int getBatchSize() { 212 return batchSize; 213 } 214 215 public void setBatchSize(int i) { 216 batchSize = i; 217 } 218 219 public FetchMode getFetchMode() { 220 return fetchMode; 221 } 222 223 public void setFetchMode(FetchMode fetchMode) { 224 this.fetchMode = fetchMode; 225 } 226 227 public void setCollectionPersisterClass(Class persister) { 228 this.collectionPersisterClass = persister; 229 } 230 231 public Class getCollectionPersisterClass() { 232 return collectionPersisterClass; 233 } 234 235 public void validate(Mapping mapping) throws MappingException { 236 if ( getKey().isCascadeDeleteEnabled() && ( !isInverse() || !isOneToMany() ) ) { 237 throw new MappingException( 238 "only inverse one-to-many associations may use on-delete=\"cascade\": " 239 + getRole() ); 240 } 241 if ( !getKey().isValid( mapping ) ) { 242 throw new MappingException( 243 "collection foreign key mapping has wrong number of columns: " 244 + getRole() 245 + " type: " 246 + getKey().getType().getName() ); 247 } 248 if ( !getElement().isValid( mapping ) ) { 249 throw new MappingException( 250 "collection element mapping has wrong number of columns: " 251 + getRole() 252 + " type: " 253 + getElement().getType().getName() ); 254 } 255 256 checkColumnDuplication(); 257 258 if ( elementNodeName!=null && elementNodeName.startsWith("@") ) { 259 throw new MappingException("element node must not be an attribute: " + elementNodeName ); 260 } 261 if ( elementNodeName!=null && elementNodeName.equals(".") ) { 262 throw new MappingException("element node must not be the parent: " + elementNodeName ); 263 } 264 if ( nodeName!=null && nodeName.indexOf('@')>-1 ) { 265 throw new MappingException("collection node must not be an attribute: " + elementNodeName ); 266 } 267 } 268 269 private void checkColumnDuplication(java.util.Set distinctColumns, Iterator columns) 270 throws MappingException { 271 while ( columns.hasNext() ) { 272 Selectable s = (Selectable) columns.next(); 273 if ( !s.isFormula() ) { 274 Column col = (Column) s; 275 if ( !distinctColumns.add( col.getName() ) ) { 276 throw new MappingException( "Repeated column in mapping for collection: " 277 + getRole() 278 + " column: " 279 + col.getName() ); 280 } 281 } 282 } 283 } 284 285 private void checkColumnDuplication() throws MappingException { 286 HashSet cols = new HashSet (); 287 checkColumnDuplication( cols, getKey().getColumnIterator() ); 288 if ( isIndexed() ) { 289 checkColumnDuplication( cols, ( (IndexedCollection) this ) 290 .getIndex() 291 .getColumnIterator() ); 292 } 293 if ( isIdentified() ) { 294 checkColumnDuplication( cols, ( (IdentifierCollection) this ) 295 .getIdentifier() 296 .getColumnIterator() ); 297 } 298 if ( !isOneToMany() ) { 299 checkColumnDuplication( cols, getElement().getColumnIterator() ); 300 } 301 } 302 303 public Iterator getColumnIterator() { 304 return EmptyIterator.INSTANCE; 305 } 306 307 public int getColumnSpan() { 308 return 0; 309 } 310 311 public Type getType() throws MappingException { 312 return getCollectionType(); 313 } 314 315 public CollectionType getCollectionType() { 316 if ( typeName == null ) { 317 return getDefaultCollectionType(); 318 } 319 else { 320 return TypeFactory.customCollection( typeName, role, referencedPropertyName, isEmbedded() ); 321 } 322 } 323 324 public boolean isNullable() { 325 return true; 326 } 327 328 public boolean isAlternateUniqueKey() { 329 return false; 330 } 331 332 public Table getTable() { 333 return owner.getTable(); 334 } 335 336 public void createForeignKey() { 337 } 338 339 public boolean isSimpleValue() { 340 return false; 341 } 342 343 public boolean isValid(Mapping mapping) throws MappingException { 344 return true; 345 } 346 347 private void createForeignKeys() throws MappingException { 348 if ( referencedPropertyName == null ) { 350 getElement().createForeignKey(); 351 key.createForeignKeyOfEntity( getOwner().getEntityName() ); 352 } 353 } 355 356 abstract void createPrimaryKey(); 357 358 public void createAllKeys() throws MappingException { 359 createForeignKeys(); 360 if ( !isInverse() ) createPrimaryKey(); 361 } 362 363 public String getCacheConcurrencyStrategy() { 364 return cacheConcurrencyStrategy; 365 } 366 367 public void setCacheConcurrencyStrategy(String cacheConcurrencyStrategy) { 368 this.cacheConcurrencyStrategy = cacheConcurrencyStrategy; 369 } 370 371 public void setTypeUsingReflection(String className, String propertyName) { 372 } 373 374 public String getCacheRegionName() { 375 return cacheRegionName == null ? role : cacheRegionName; 376 } 377 378 public void setCacheRegionName(String cacheRegionName) { 379 this.cacheRegionName = cacheRegionName; 380 } 381 382 public String getCustomSQLDelete() { 383 return customSQLDelete; 384 } 385 386 public void setCustomSQLDelete(String customSQLDelete, boolean callable) { 387 this.customSQLDelete = customSQLDelete; 388 this.customDeleteCallable = callable; 389 } 390 391 public String getCustomSQLDeleteAll() { 392 return customSQLDeleteAll; 393 } 394 395 public void setCustomSQLDeleteAll(String customSQLDeleteAll, boolean callable) { 396 this.customSQLDeleteAll = customSQLDeleteAll; 397 this.customDeleteAllCallable = callable; 398 } 399 400 public String getCustomSQLInsert() { 401 return customSQLInsert; 402 } 403 404 public void setCustomSQLInsert(String customSQLInsert, boolean callable) { 405 this.customSQLInsert = customSQLInsert; 406 this.customInsertCallable = callable; 407 } 408 409 public String getCustomSQLUpdate() { 410 return customSQLUpdate; 411 } 412 413 public void setCustomSQLUpdate(String customSQLUpdate, boolean callable) { 414 this.customSQLUpdate = customSQLUpdate; 415 this.customUpdateCallable = callable; 416 } 417 418 public boolean isCustomDeleteCallable() { 419 return customDeleteCallable; 420 } 421 422 public boolean isCustomDeleteAllCallable() { 423 return customDeleteAllCallable; 424 } 425 426 public boolean isCustomInsertCallable() { 427 return customInsertCallable; 428 } 429 430 public boolean isCustomUpdateCallable() { 431 return customUpdateCallable; 432 } 433 434 public void addFilter(String name, String condition) { 435 filters.put( name, condition ); 436 } 437 438 public java.util.Map getFilterMap() { 439 return filters; 440 } 441 442 public void addManyToManyFilter(String name, String condition) { 443 manyToManyFilters.put( name, condition ); 444 } 445 446 public java.util.Map getManyToManyFilterMap() { 447 return manyToManyFilters; 448 } 449 450 public String toString() { 451 return getClass().getName() + '(' + getRole() + ')'; 452 } 453 454 public java.util.Set getSynchronizedTables() { 455 return synchronizedTables; 456 } 457 458 public String getLoaderName() { 459 return loaderName; 460 } 461 462 public void setLoaderName(String name) { 463 this.loaderName = name==null ? null : name.intern(); 464 } 465 466 public String getReferencedPropertyName() { 467 return referencedPropertyName; 468 } 469 470 public void setReferencedPropertyName(String propertyRef) { 471 this.referencedPropertyName = propertyRef==null ? null : propertyRef.intern(); 472 } 473 474 public boolean isOptimisticLocked() { 475 return optimisticLocked; 476 } 477 478 public void setOptimisticLocked(boolean optimisticLocked) { 479 this.optimisticLocked = optimisticLocked; 480 } 481 482 public boolean isMap() { 483 return false; 484 } 485 486 public String getTypeName() { 487 return typeName; 488 } 489 490 public void setTypeName(String typeName) { 491 this.typeName = typeName; 492 } 493 494 public boolean[] getColumnInsertability() { 495 return ArrayHelper.EMPTY_BOOLEAN_ARRAY; 496 } 497 498 public boolean[] getColumnUpdateability() { 499 return ArrayHelper.EMPTY_BOOLEAN_ARRAY; 500 } 501 502 public String getNodeName() { 503 return nodeName; 504 } 505 506 public void setNodeName(String nodeName) { 507 this.nodeName = nodeName; 508 } 509 510 public String getElementNodeName() { 511 return elementNodeName; 512 } 513 514 public void setElementNodeName(String elementNodeName) { 515 this.elementNodeName = elementNodeName; 516 } 517 518 public boolean isEmbedded() { 519 return embedded; 520 } 521 522 public void setEmbedded(boolean embedded) { 523 this.embedded = embedded; 524 } 525 526 public boolean isSubselectLoadable() { 527 return subselectLoadable; 528 } 529 530 531 public void setSubselectLoadable(boolean subqueryLoadable) { 532 this.subselectLoadable = subqueryLoadable; 533 } 534 535 public boolean isMutable() { 536 return mutable; 537 } 538 539 public void setMutable(boolean mutable) { 540 this.mutable = mutable; 541 } 542 543 544 } | Popular Tags |