public void validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo) { Iterator iter = getColumnIterator(); while (iter.hasNext()) { Column col = (Column) iter.next(); ColumnMetadata columnInfo = tableInfo.getColumnMetadata(col.getName()); if (columnInfo == null) { throw new HibernateException( "Missing column: " + col.getName() + " in " + Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName())); } else { final boolean typesMatch = col.getSqlType(dialect, mapping) .toLowerCase(Locale.ROOT) .startsWith(columnInfo.getTypeName().toLowerCase(Locale.ROOT)) || columnInfo.getTypeCode() == col.getSqlTypeCode(mapping); if (!typesMatch) { throw new HibernateException( "Wrong column type in " + Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName()) + " for column " + col.getName() + ". Found: " + columnInfo.getTypeName().toLowerCase(Locale.ROOT) + ", expected: " + col.getSqlType(dialect, mapping)); } } } }
public void visit(Configuration cfg, Table table, Column col, IssueCollector pc) { if (currentDbTable == null) { return; } Column dbColumn = currentDbTable.getColumn(new Column(col.getName())); if (dbColumn == null) { pc.reportIssue( new Issue( "SCHEMA_COLUMN_MISSING", Issue.HIGH_PRIORITY, table(table) + " is missing column: " + col.getName())); } else { // TODO: this needs to be able to know if a type is truly compatible or not. Right now it // requires an exact match. // String sqlType = col.getSqlType( dialect, mapping ); int dbTypeCode = dbColumn.getSqlTypeCode().intValue(); int modelTypeCode = col.getSqlTypeCode(mapping); // TODO: sqltype name string if (!(dbTypeCode == modelTypeCode)) { pc.reportIssue( new Issue( "SCHEMA_COLUMN_TYPE_MISMATCH", Issue.NORMAL_PRIORITY, table(table) + " has a wrong column type for " + col.getName() + ", expected: " + JDBCToHibernateTypeHelper.getJDBCTypeName(modelTypeCode) + " but was " + JDBCToHibernateTypeHelper.getJDBCTypeName(dbTypeCode) + " in db")); } } }
public String sqlCreateString( Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) throws HibernateException { StringBuffer buf = new StringBuffer("create table ") .append(getQualifiedName(dialect, defaultCatalog, defaultSchema)) .append(" ("); boolean identityColumn = idValue != null && idValue.isIdentityColumn(dialect); // Try to find out the name of the primary key to create it as identity if the IdentityGenerator // is used String pkname = null; if (hasPrimaryKey() && identityColumn) { pkname = ((Column) getPrimaryKey().getColumnIterator().next()).getQuotedName(dialect); } Iterator iter = getColumnIterator(); while (iter.hasNext()) { Column col = (Column) iter.next(); buf.append(col.getQuotedName(dialect)).append(' '); if (identityColumn && col.getQuotedName(dialect).equals(pkname)) { // to support dialects that have their own identity data type if (dialect.hasDataTypeInIdentityColumn()) { buf.append(col.getSqlType(dialect, p)); } buf.append(' ').append(dialect.getIdentityColumnString(col.getSqlTypeCode(p))); } else { buf.append(col.getSqlType(dialect, p)); String defaultValue = col.getDefaultValue(); if (defaultValue != null) { buf.append(" default ").append(defaultValue); } if (col.isNullable()) { buf.append(dialect.getNullColumnString()); } else { buf.append(" not null"); } } boolean useUniqueConstraint = col.isUnique() && (!col.isNullable() || dialect.supportsNotNullUnique()); if (useUniqueConstraint) { if (dialect.supportsUnique()) { buf.append(" unique"); } else { UniqueKey uk = getOrCreateUniqueKey(col.getQuotedName(dialect) + '_'); uk.addColumn(col); } } if (col.hasCheckConstraint() && dialect.supportsColumnCheck()) { buf.append(" check (").append(col.getCheckConstraint()).append(")"); } String columnComment = col.getComment(); if (columnComment != null) { buf.append(dialect.getColumnComment(columnComment)); } if (iter.hasNext()) buf.append(", "); } if (hasPrimaryKey()) { buf.append(", ").append(getPrimaryKey().sqlConstraintString(dialect)); } if (dialect.supportsUniqueConstraintInCreateAlterTable()) { Iterator ukiter = getUniqueKeyIterator(); while (ukiter.hasNext()) { UniqueKey uk = (UniqueKey) ukiter.next(); buf.append(", ").append(uk.sqlConstraintString(dialect)); } } /*Iterator idxiter = getIndexIterator(); while ( idxiter.hasNext() ) { Index idx = (Index) idxiter.next(); buf.append(',').append( idx.sqlConstraintString(dialect) ); }*/ if (dialect.supportsTableCheck()) { Iterator chiter = checkConstraints.iterator(); while (chiter.hasNext()) { buf.append(", check (").append(chiter.next()).append(')'); } } buf.append(')'); if (comment != null) buf.append(dialect.getTableComment(comment)); return buf.append(dialect.getTableTypeString()).toString(); }
public String sqlCreateString( Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) { StringBuilder buf = new StringBuilder( hasPrimaryKey() ? dialect.getCreateTableString() : dialect.getCreateMultisetTableString()) .append(' ') .append(getQualifiedName(dialect, defaultCatalog, defaultSchema)) .append(" ("); boolean identityColumn = idValue != null && idValue.isIdentityColumn(p.getIdentifierGeneratorFactory(), dialect); // Try to find out the name of the primary key to create it as identity if the IdentityGenerator // is used String pkname = null; if (hasPrimaryKey() && identityColumn) { pkname = ((Column) getPrimaryKey().getColumnIterator().next()).getQuotedName(dialect); } Iterator iter = getColumnIterator(); while (iter.hasNext()) { Column col = (Column) iter.next(); buf.append(col.getQuotedName(dialect)).append(' '); if (identityColumn && col.getQuotedName(dialect).equals(pkname)) { // to support dialects that have their own identity data type if (dialect.getIdentityColumnSupport().hasDataTypeInIdentityColumn()) { buf.append(col.getSqlType(dialect, p)); } buf.append(' ') .append( dialect.getIdentityColumnSupport().getIdentityColumnString(col.getSqlTypeCode(p))); } else { buf.append(col.getSqlType(dialect, p)); String defaultValue = col.getDefaultValue(); if (defaultValue != null) { buf.append(" default ").append(defaultValue); } if (col.isNullable()) { buf.append(dialect.getNullColumnString()); } else { buf.append(" not null"); } } if (col.isUnique()) { String keyName = Constraint.generateName("UK_", this, col); UniqueKey uk = getOrCreateUniqueKey(keyName); uk.addColumn(col); buf.append(dialect.getUniqueDelegate().getColumnDefinitionUniquenessFragment(col)); } if (col.hasCheckConstraint() && dialect.supportsColumnCheck()) { buf.append(" check (").append(col.getCheckConstraint()).append(")"); } String columnComment = col.getComment(); if (columnComment != null) { buf.append(dialect.getColumnComment(columnComment)); } if (iter.hasNext()) { buf.append(", "); } } if (hasPrimaryKey()) { buf.append(", ").append(getPrimaryKey().sqlConstraintString(dialect)); } buf.append(dialect.getUniqueDelegate().getTableCreationUniqueConstraintsFragment(this)); if (dialect.supportsTableCheck()) { for (String checkConstraint : checkConstraints) { buf.append(", check (").append(checkConstraint).append(')'); } } buf.append(')'); if (comment != null) { buf.append(dialect.getTableComment(comment)); } return buf.append(dialect.getTableTypeString()).toString(); }
/** * @param column * @param generatedIdentifier * @return */ private String guessAndAlignType( Table table, Column column, Mapping mapping, boolean generatedIdentifier) { // TODO: this method mutates the column if the types does not match...not good. // maybe we should copy the column instead before calling this method. Integer sqlTypeCode = column.getSqlTypeCode(); String location = "Table: " + Table.qualify(table.getCatalog(), table.getSchema(), table.getQuotedName()) + " column: " + column.getQuotedName(); if (sqlTypeCode == null) { throw new JDBCBinderException("sqltype is null for " + location); } String preferredHibernateType = revengStrategy.columnToHibernateTypeName( TableIdentifier.create(table), column.getName(), sqlTypeCode.intValue(), column.getLength(), column.getPrecision(), column.getScale(), column.isNullable(), generatedIdentifier); Type wantedType = TypeFactory.heuristicType(preferredHibernateType); if (wantedType != null) { int[] wantedSqlTypes = wantedType.sqlTypes(mapping); if (wantedSqlTypes.length > 1) { throw new JDBCBinderException( "The type " + preferredHibernateType + " found on " + location + " spans multiple columns. Only single column types allowed."); } int wantedSqlType = wantedSqlTypes[0]; if (wantedSqlType != sqlTypeCode.intValue()) { log.debug( "Sql type mismatch for " + location + " between DB and wanted hibernate type. Sql type set to " + typeCodeName(sqlTypeCode.intValue()) + " instead of " + typeCodeName(wantedSqlType)); column.setSqlTypeCode(new Integer(wantedSqlType)); } } else { log.debug( "No Hibernate type found for " + preferredHibernateType + ". Most likely cause is a missing UserType class."); } if (preferredHibernateType == null) { throw new JDBCBinderException( "Could not find javatype for " + typeCodeName(sqlTypeCode.intValue())); } return preferredHibernateType; }
/** * @param rc * @param processed * @param table * @param object */ private Property bindOneToMany( PersistentClass rc, ForeignKey foreignKey, Set processed, Mapping mapping) { Table collectionTable = foreignKey.getTable(); // Collection collection = new org.hibernate.mapping.Set(rc); // MASTER TODO: allow overriding // collection type Collection collection = new org.hibernate.mapping.List(rc); // MASTER TODO: allow overriding collection type collection.setCollectionTable(collectionTable); // CHILD+ boolean manyToMany = revengStrategy.isManyToManyTable(collectionTable); if (manyToMany) { // log.debug("Rev.eng said here is a many-to-many"); // TODO: handle "the other side should influence the name" } if (manyToMany) { ManyToOne element = new ManyToOne(collection.getCollectionTable()); // TODO: find the other foreignkey and choose the other side. Iterator foreignKeyIterator = foreignKey.getTable().getForeignKeyIterator(); List keys = new ArrayList(); while (foreignKeyIterator.hasNext()) { Object next = foreignKeyIterator.next(); if (next != foreignKey) { keys.add(next); } } if (keys.size() > 1) { throw new JDBCBinderException( "more than one other foreign key to choose from!"); // todo: handle better ? } ForeignKey fk = (ForeignKey) keys.get(0); String tableToClassName = bindCollection(rc, foreignKey, fk, collection); element.setReferencedEntityName(tableToClassName); element.addColumn(fk.getColumn(0)); collection.setElement(element); } else { String tableToClassName = bindCollection(rc, foreignKey, null, collection); OneToMany oneToMany = new OneToMany(collection.getOwner()); oneToMany.setReferencedEntityName(tableToClassName); // Child mappings.addSecondPass(new JDBCCollectionSecondPass(mappings, collection)); collection.setElement(oneToMany); } // bind keyvalue KeyValue referencedKeyValue; String propRef = collection.getReferencedPropertyName(); if (propRef == null) { referencedKeyValue = collection.getOwner().getIdentifier(); } else { referencedKeyValue = (KeyValue) collection.getOwner().getProperty(propRef).getValue(); } SimpleValue keyValue = new DependantValue(collectionTable, referencedKeyValue); // keyValue.setForeignKeyName("none"); // Avoid creating the foreignkey // key.setCascadeDeleteEnabled( "cascade".equals( subnode.attributeValue("on-delete") ) ); Iterator columnIterator = foreignKey.getColumnIterator(); while (columnIterator.hasNext()) { Column fkcolumn = (Column) columnIterator.next(); if (fkcolumn.getSqlTypeCode() != null) { // TODO: user defined foreign ref columns does not have a type set. guessAndAlignType( collectionTable, fkcolumn, mapping, false); // needed to ensure foreign key columns has same type as the "property" column. } keyValue.addColumn(fkcolumn); } collection.setKey(keyValue); mappings.addCollection(collection); return makeCollectionProperty( StringHelper.unqualify(collection.getRole()), true, rc.getTable(), foreignKey, collection, true); // return makeProperty(TableIdentifier.create( rc.getTable() ), StringHelper.unqualify( // collection.getRole() ), collection, true, true, true, "none", null); // TODO: cascade isn't // all by default }