/** Shallow copy, the value is not copied */ protected Object clone() { Column copy = new Column(); copy.setLength(length); copy.setScale(scale); copy.setValue(value); copy.setTypeIndex(typeIndex); copy.setName(getQuotedName()); copy.setNullable(nullable); copy.setPrecision(precision); copy.setUnique(unique); copy.setSqlType(sqlType); copy.setSqlTypeCode(sqlTypeCode); copy.uniqueInteger = uniqueInteger; // usually useless copy.setCheckConstraint(checkConstraint); copy.setComment(comment); copy.setDefaultValue(defaultValue); copy.setCustomRead(customRead); copy.setCustomWrite(customWrite); return copy; }
/** * Builds the <code>Join</code> instance for the mapped by side of a <i>OneToOne</i> association * using a join tables. * * <p>Note:<br> * * <ul> * <li>From the mappedBy side we should not create the PK nor the FK, this is handled from the * other side. * <li>This method is a dirty dupe of EntityBinder.bindSecondaryTable</i>. */ private Join buildJoinFromMappedBySide( PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) { Join join = new Join(); join.setPersistentClass(persistentClass); // no check constraints available on joins join.setTable(originalJoin.getTable()); join.setInverse(true); SimpleValue key = new DependantValue(mappings, join.getTable(), persistentClass.getIdentifier()); // TODO support @ForeignKey join.setKey(key); join.setSequentialSelect(false); // TODO support for inverse and optional join.setOptional(true); // perhaps not quite per-spec, but a Good Thing anyway key.setCascadeDeleteEnabled(false); Iterator mappedByColumns = otherSideProperty.getValue().getColumnIterator(); while (mappedByColumns.hasNext()) { Column column = (Column) mappedByColumns.next(); Column copy = new Column(); copy.setLength(column.getLength()); copy.setScale(column.getScale()); copy.setValue(key); copy.setName(column.getQuotedName()); copy.setNullable(column.isNullable()); copy.setPrecision(column.getPrecision()); copy.setUnique(column.isUnique()); copy.setSqlType(column.getSqlType()); copy.setCheckConstraint(column.getCheckConstraint()); copy.setComment(column.getComment()); copy.setDefaultValue(column.getDefaultValue()); key.addColumn(copy); } persistentClass.addJoin(join); return join; }
public static void processBasicColumns( MetaDataDialect metaDataDialect, ReverseEngineeringStrategy revengStrategy, String defaultSchema, String defaultCatalog, Table table, ProgressListener progress) { String qualify = TableNameQualifier.qualify(table.getCatalog(), table.getSchema(), table.getName()); Iterator<?> columnIterator = null; try { Map<?, ?> columnRs = null; log.debug("Finding columns for " + qualify); progress.startSubTask("Finding columns for " + qualify); columnIterator = metaDataDialect.getColumns( getCatalogForDBLookup(table.getCatalog(), defaultCatalog), getSchemaForDBLookup(table.getSchema(), defaultSchema), table.getName(), null); // dumpHeader(columnRs); while (columnIterator.hasNext()) { // dumpRow(columnRs); columnRs = (Map<?, ?>) columnIterator.next(); String tableName = (String) columnRs.get("TABLE_NAME"); int sqlType = ((Integer) columnRs.get("DATA_TYPE")).intValue(); // String sqlTypeName = (String) columnRs.get("TYPE_NAME"); String columnName = (String) columnRs.get("COLUMN_NAME"); String comment = (String) columnRs.get("REMARKS"); TableIdentifier ti = RevEngUtils.createTableIdentifier(table, defaultCatalog, defaultSchema); if (revengStrategy.excludeColumn(ti, columnName)) { log.debug("Column " + ti + "." + columnName + " excluded by strategy"); continue; } if (!tableName.equals(table.getName())) { log.debug( "Table name " + tableName + " does not match requested " + table.getName() + ". Ignoring column " + columnName + " since it either is invalid or a duplicate"); continue; } // String columnDefaultValue = columnRs.getString("COLUMN_DEF"); TODO: only read if have a // way to avoid issues with clobs/lobs and similar int dbNullability = ((Integer) columnRs.get("NULLABLE")).intValue(); boolean isNullable = true; switch (dbNullability) { case DatabaseMetaData.columnNullable: case DatabaseMetaData.columnNullableUnknown: isNullable = true; break; case DatabaseMetaData.columnNoNulls: isNullable = false; break; default: isNullable = true; } int size = ((Integer) columnRs.get("COLUMN_SIZE")).intValue(); int decimalDigits = ((Integer) columnRs.get("DECIMAL_DIGITS")).intValue(); Column column = new Column(); column.setName(quote(columnName, metaDataDialect)); Column existing = table.getColumn(column); if (existing != null) { // TODO: should we just pick it up and fill it up with whatever we get from the db instead // ? throw new JDBCBinderException(column + " already exists in " + qualify); } // TODO: column.setSqlType(sqlTypeName); //this does not work 'cos the // precision/scale/length are not retured in TYPE_NAME // column.setSqlType(sqlTypeName); column.setComment(comment); column.setSqlTypeCode(new Integer(sqlType)); if (intBounds(size)) { if (JDBCToHibernateTypeHelper.typeHasLength(sqlType)) { column.setLength(size); } if (JDBCToHibernateTypeHelper.typeHasScaleAndPrecision(sqlType)) { column.setPrecision(size); } } if (intBounds(decimalDigits)) { if (JDBCToHibernateTypeHelper.typeHasScaleAndPrecision(sqlType)) { column.setScale(decimalDigits); } } column.setNullable(isNullable); // columnDefaultValue is useless for Hibernate // isIndexed (available via Indexes) // unique - detected when getting indexes // isPk - detected when finding primary keys table.addColumn(column); } } finally { if (columnIterator != null) { try { metaDataDialect.close(columnIterator); } catch (JDBCException se) { log.warn("Exception while closing iterator for column meta data", se); } } } }
// TODO refactor this code, there is a lot of duplication in this method public void doSecondPass(Map persistentClasses) throws MappingException { org.hibernate.mapping.OneToOne value = new org.hibernate.mapping.OneToOne( mappings, propertyHolder.getTable(), propertyHolder.getPersistentClass()); final String propertyName = inferredData.getPropertyName(); value.setPropertyName(propertyName); String referencedEntityName = ToOneBinder.getReferenceEntityName(inferredData, targetEntity, mappings); value.setReferencedEntityName(referencedEntityName); AnnotationBinder.defineFetchingStrategy(value, inferredData.getProperty()); // value.setFetchMode( fetchMode ); value.setCascadeDeleteEnabled(cascadeOnDelete); // value.setLazy( fetchMode != FetchMode.JOIN ); if (!optional) value.setConstrained(true); value.setForeignKeyType( value.isConstrained() ? ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT : ForeignKeyDirection.FOREIGN_KEY_TO_PARENT); PropertyBinder binder = new PropertyBinder(); binder.setName(propertyName); binder.setValue(value); binder.setCascade(cascadeStrategy); binder.setAccessType(inferredData.getDefaultAccess()); Property prop = binder.makeProperty(); if (BinderHelper.isEmptyAnnotationValue(mappedBy)) { /* * we need to check if the columns are in the right order * if not, then we need to create a many to one and formula * but actually, since entities linked by a one to one need * to share the same composite id class, this cannot happen in hibernate */ boolean rightOrder = true; if (rightOrder) { String path = StringHelper.qualify(propertyHolder.getPath(), propertyName); (new ToOneFkSecondPass( value, joinColumns, !optional, // cannot have nullabe and unique on certain DBs propertyHolder.getEntityOwnerClassName(), path, mappings)) .doSecondPass(persistentClasses); // no column associated since its a one to one propertyHolder.addProperty(prop, inferredData.getDeclaringClass()); } else { // this is a many to one with Formula } } else { PersistentClass otherSide = (PersistentClass) persistentClasses.get(value.getReferencedEntityName()); Property otherSideProperty; try { if (otherSide == null) { throw new MappingException("Unable to find entity: " + value.getReferencedEntityName()); } otherSideProperty = BinderHelper.findPropertyByName(otherSide, mappedBy); } catch (MappingException e) { throw new AnnotationException( "Unknown mappedBy in: " + StringHelper.qualify(ownerEntity, ownerProperty) + ", referenced property unknown: " + StringHelper.qualify(value.getReferencedEntityName(), mappedBy)); } if (otherSideProperty == null) { throw new AnnotationException( "Unknown mappedBy in: " + StringHelper.qualify(ownerEntity, ownerProperty) + ", referenced property unknown: " + StringHelper.qualify(value.getReferencedEntityName(), mappedBy)); } if (otherSideProperty.getValue() instanceof OneToOne) { propertyHolder.addProperty(prop, inferredData.getDeclaringClass()); } else if (otherSideProperty.getValue() instanceof ManyToOne) { Iterator it = otherSide.getJoinIterator(); Join otherSideJoin = null; while (it.hasNext()) { Join otherSideJoinValue = (Join) it.next(); if (otherSideJoinValue.containsProperty(otherSideProperty)) { otherSideJoin = otherSideJoinValue; break; } } if (otherSideJoin != null) { // @OneToOne @JoinTable Join mappedByJoin = buildJoinFromMappedBySide( (PersistentClass) persistentClasses.get(ownerEntity), otherSideProperty, otherSideJoin); ManyToOne manyToOne = new ManyToOne(mappings, mappedByJoin.getTable()); // FIXME use ignore not found here manyToOne.setIgnoreNotFound(ignoreNotFound); manyToOne.setCascadeDeleteEnabled(value.isCascadeDeleteEnabled()); manyToOne.setEmbedded(value.isEmbedded()); manyToOne.setFetchMode(value.getFetchMode()); manyToOne.setLazy(value.isLazy()); manyToOne.setReferencedEntityName(value.getReferencedEntityName()); manyToOne.setUnwrapProxy(value.isUnwrapProxy()); prop.setValue(manyToOne); Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator(); while (otherSideJoinKeyColumns.hasNext()) { Column column = (Column) otherSideJoinKeyColumns.next(); Column copy = new Column(); copy.setLength(column.getLength()); copy.setScale(column.getScale()); copy.setValue(manyToOne); copy.setName(column.getQuotedName()); copy.setNullable(column.isNullable()); copy.setPrecision(column.getPrecision()); copy.setUnique(column.isUnique()); copy.setSqlType(column.getSqlType()); copy.setCheckConstraint(column.getCheckConstraint()); copy.setComment(column.getComment()); copy.setDefaultValue(column.getDefaultValue()); manyToOne.addColumn(copy); } mappedByJoin.addProperty(prop); } else { propertyHolder.addProperty(prop, inferredData.getDeclaringClass()); } value.setReferencedPropertyName(mappedBy); String propertyRef = value.getReferencedPropertyName(); if (propertyRef != null) { mappings.addUniquePropertyReference(value.getReferencedEntityName(), propertyRef); } } else { throw new AnnotationException( "Referenced property not a (One|Many)ToOne: " + StringHelper.qualify(otherSide.getEntityName(), mappedBy) + " in mappedBy of " + StringHelper.qualify(ownerEntity, ownerProperty)); } } ForeignKey fk = inferredData.getProperty().getAnnotation(ForeignKey.class); String fkName = fk != null ? fk.name() : ""; if (!BinderHelper.isEmptyAnnotationValue(fkName)) value.setForeignKeyName(fkName); }