1 package org.hibernate.cfg.annotations; 3 4 import java.util.ArrayList ; 5 import java.util.HashMap ; 6 import java.util.HashSet ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 import java.util.Map ; 10 import java.util.Set ; 11 12 import org.apache.commons.logging.Log; 13 import org.apache.commons.logging.LogFactory; 14 import org.hibernate.AnnotationException; 15 import org.hibernate.AssertionFailure; 16 import org.hibernate.annotations.Index; 17 import org.hibernate.cfg.AnnotationBinder; 18 import org.hibernate.cfg.Ejb3JoinColumn; 19 import org.hibernate.cfg.ExtendedMappings; 20 import org.hibernate.mapping.Collection; 21 import org.hibernate.mapping.Column; 22 import org.hibernate.mapping.DependantValue; 23 import org.hibernate.mapping.PersistentClass; 24 import org.hibernate.mapping.Property; 25 import org.hibernate.mapping.SimpleValue; 26 import org.hibernate.mapping.Table; 27 import org.hibernate.mapping.ToOne; 28 import org.hibernate.mapping.Value; 29 import org.hibernate.util.StringHelper; 30 31 35 public abstract class TableBinder { 36 private static Log log = LogFactory.getLog(TableBinder.class); 38 39 public static Table fillTable( 40 String schema, String catalog, String realTableName, boolean isAbstract, 41 List uniqueConstraints, String constraints, Table denormalizedSuperTable, ExtendedMappings mappings 42 ) { 43 schema = AnnotationBinder.isDefault(schema) ? schema = mappings.getSchemaName() : schema; 44 catalog = AnnotationBinder.isDefault(catalog) ? catalog = mappings.getCatalogName() : catalog; 45 Table table; 46 if (denormalizedSuperTable != null) { 47 table = mappings.addDenormalizedTable( 48 schema, 49 catalog, 50 realTableName, 51 isAbstract, 52 null, denormalizedSuperTable 54 ); 55 } 56 else { 57 table = mappings.addTable( 58 schema, 59 catalog, 60 realTableName, 61 null, isAbstract 63 ); 64 } 65 if (uniqueConstraints != null && uniqueConstraints.size() > 0) 66 mappings.addUniqueConstraints(table, uniqueConstraints); 67 if (constraints != null) table.addCheckConstraint(constraints); 68 return table; 69 } 70 71 77 public static void bindManytoManyInverseFk( 78 PersistentClass referencedEntity, Ejb3JoinColumn[] columns, SimpleValue value, boolean unique, 79 ExtendedMappings mappings 80 ) { 81 if ( ! StringHelper.isEmpty( columns[0].getMappedBy() ) ) { 82 final Property property = referencedEntity.getProperty( columns[0].getMappedBy() ); 83 Iterator mappedByColumns = ( (Collection) property.getValue() ).getKey().getColumnIterator(); 84 while ( mappedByColumns.hasNext() ) { 85 Column column = (Column) mappedByColumns.next(); 86 columns[0].linkValueUsingAColumnCopy(column, value); 87 } 88 value.createForeignKey(); 89 } 90 else { 91 bindFk(referencedEntity, null, columns, value, unique ); 92 } 93 } 94 95 public static void bindFk( 96 PersistentClass referencedEntity, PersistentClass destinationEntity, Ejb3JoinColumn[] columns, SimpleValue value, 97 boolean unique 98 ) { 99 PersistentClass associatedClass; 100 if (destinationEntity != null) { 101 associatedClass = destinationEntity; 103 } 104 else { 105 associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder().getPersistentClass(); 106 } 107 final String mappedByProperty = columns[0].getMappedBy(); 108 if ( ! StringHelper.isEmpty( mappedByProperty ) ) { 109 113 if ( log.isDebugEnabled() ) log.debug("Retrieving property " + associatedClass.getEntityName() + "." + mappedByProperty ); 114 115 final Property property = associatedClass.getProperty( columns[0].getMappedBy() ); 116 Iterator mappedByColumns; 117 if ( property.getValue() instanceof Collection) { 118 mappedByColumns = ( (Collection) property.getValue() ).getElement().getColumnIterator(); 119 } 120 else { 121 mappedByColumns = property.getValue().getColumnIterator(); 122 } 123 while ( mappedByColumns.hasNext() ) { 124 Column column = (Column) mappedByColumns.next(); 125 columns[0].linkValueUsingAColumnCopy(column, value); 126 } 127 } else if ( columns[0].isImplicit() ) { 128 132 Iterator idColumns = referencedEntity.getIdentifier().getColumnIterator(); 133 while ( idColumns.hasNext() ) { 134 Column column = (Column) idColumns.next(); 135 columns[0].linkValueUsingDefaultColumnNaming(column, value); 136 } 137 } 138 else { 139 int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType(columns, referencedEntity); 140 141 if ( Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum ) { 142 String referencedPropertyName; 143 if (value instanceof ToOne) { 144 referencedPropertyName = ( (ToOne) value ).getReferencedPropertyName(); 145 } 146 else if (value instanceof DependantValue) { 147 Collection collection = (Collection) referencedEntity.getProperty( columns[0].getPropertyName() ).getValue(); 148 referencedPropertyName = collection.getReferencedPropertyName(); 149 } 150 else { 151 throw new AssertionFailure("Do a property ref on an unexpected Value type: " 152 + value.getClass().getName() ); 153 } 154 if (referencedPropertyName == null) throw new AssertionFailure("No property ref found while expected"); 155 Property synthProp = referencedEntity.getProperty( referencedPropertyName ); 156 if (synthProp == null) throw new AssertionFailure("Cannot find synthProp: " + referencedEntity.getEntityName() + "." + referencedPropertyName ); 157 linkColumnWithValueOverridingNameIfImplicit( synthProp.getColumnIterator(), columns, value ); 158 159 } 160 else { 161 if ( Ejb3JoinColumn.NO_REFERENCE == fkEnum ) { 162 if (columns.length != referencedEntity.getIdentifier().getColumnSpan() ) { 164 throw new AnnotationException("A Foreign key refering " + referencedEntity.getEntityName() 165 + " has the wrong number of column. should be " + referencedEntity.getIdentifier().getColumnSpan() 166 ); 167 } 168 linkColumnWithValueOverridingNameIfImplicit( 170 referencedEntity.getIdentifier().getColumnIterator(), 171 columns, 172 value 173 ); 174 } 175 else { 176 Iterator idColItr = referencedEntity.getIdentifier().getColumnIterator(); 178 org.hibernate.mapping.Column col; 179 if (! idColItr.hasNext()) log.debug("No column in the identifier!"); 180 while ( idColItr.hasNext() ) { 181 boolean match = false; 182 col = (org.hibernate.mapping.Column) idColItr.next(); 184 for (Ejb3JoinColumn joinCol : columns) { 185 if ( joinCol.getReferencedColumn().equals( col.getName() ) ) { 186 if ( joinCol.isNameDeferred() ) { 188 joinCol.redefineColumnName( joinCol.getPropertyName() + "_" + joinCol.getReferencedColumn() ); 189 } 190 joinCol.linkWithValue(value); 191 match = true; 192 break; 193 } 194 } 195 if (match == false) { 196 throw new AnnotationException("Column name " + col.getName() + " of " 197 + referencedEntity.getEntityName() + " not found in JoinColumns.referencedColumnName"); 198 } 199 } 200 } 201 } 202 } 203 204 value.createForeignKey(); 277 if ( unique == true ) { 278 createUniqueConstraint( value ); 279 } 280 } 281 282 private static void linkColumnWithValueOverridingNameIfImplicit(Iterator columnIterator, Ejb3JoinColumn[] columns, SimpleValue value) { 283 for (Ejb3JoinColumn joinCol : columns) { 284 Column synthCol = (Column) columnIterator.next(); 285 if ( joinCol.isNameDeferred() ) { 286 joinCol.redefineColumnName( joinCol.getPropertyName() + "_" + synthCol.getName() ); 288 } 289 joinCol.linkWithValue(value); 290 } 291 } 292 293 public static void createUniqueConstraint(Value value) { 294 Iterator iter = value.getColumnIterator(); 295 ArrayList cols = new ArrayList (); 296 while ( iter.hasNext() ) { 297 cols.add( iter.next() ); 298 } 299 value.getTable().createUniqueKey( cols ); 300 } 301 302 private static List <Property> findPropertiesByColumns(PersistentClass referencedEntity, Ejb3JoinColumn[] columns) { 303 Map <Column,Set <Property>> columnsToProperty = new HashMap <Column,Set <Property>>(); 304 List <Column> orderedColumns = new ArrayList <Column>(); 305 for(int index = 0 ; index < columns.length ; index++) { 306 Column column = new Column( columns[index].getReferencedColumn() ); 307 orderedColumns.add( column ); 308 columnsToProperty.put( column, new HashSet <Property>() ); 309 } 310 Iterator it = referencedEntity.getPropertyIterator(); 311 while ( it.hasNext() ) { 312 Property property = (Property) it.next(); 313 Iterator columnIt = property.getColumnIterator(); 314 while ( columnIt.hasNext() ) { 315 Column column = (Column) columnIt.next(); 316 if ( columnsToProperty.containsKey( column ) ) { 317 columnsToProperty.get( column ).add( property ); 318 } 319 } 320 } 321 List <Property> orderedProperties = new ArrayList <Property>(); 325 for (Column column : orderedColumns) { 326 boolean found = false; 327 for (Property property : columnsToProperty.get( column ) ) { 328 if (property.getColumnSpan() == 1) { 329 orderedProperties.add(property); 330 found = true; 331 break; 332 } 333 } 334 if (!found) return null; } 336 return orderedProperties; 337 } 338 339 public static void addIndexes(Table hibTable, Index[] indexes) { 340 for ( Index index : indexes ) { 341 String indexName = index.name(); 342 for ( String columnName : index.columnNames() ) { 343 Column column = hibTable.getColumn( new Column(columnName) ); 344 if (column == null) throw new AnnotationException( "@Index references a unknown column: " + columnName ); 345 hibTable.getOrCreateIndex( indexName ).addColumn( column ); 346 } 347 } 348 } 349 } 350 | Popular Tags |