我正在从php / doctrine迁移到java / hibernate。在这种情况下,我需要hibernate中的命名策略应该与doctrine中的相同。
所以,我已经实现了自定义ImplicitNamingStrategy。 我使用 fk_XXX , uniq_XXX , idx_XXX 作为索引命名的模板。 外键工作正常,但唯一键没有。似乎hibernate使用旧命名策略来获取唯一键。我知道了 控制台中的下一条消息:
index.js
因此,在我的策略中,这种键应该命名为uniq_XXX。是否可以将所有唯一键的命名替换为我的策略?
更新
像这样声明的约束可以正常工作:
constraint "uk_g8hr207ijpxlwu10pewyo65gv" of relation "language" does not exist, skipping
像这样声明的Constrints有问题:
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "display_number")})
ImplicitNamingStrategyDoctrineImpl.java:
@Column(nullable = true, unique = true)
protected Integer displayNumber;
DoctrineNamingHelper.java:
package ru.tvip.support.naming;
import org.hibernate.HibernateException;
import org.hibernate.boot.model.naming.*;
import org.hibernate.boot.model.source.spi.AttributePath;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.util.StringHelper;
import java.io.Serializable;
import java.util.Locale;
/**
* Emulates PHP Doctrine naming strategy.
*/
public class ImplicitNamingStrategyDoctrineImpl implements ImplicitNamingStrategy, Serializable {
@Override
public Identifier determinePrimaryTableName(ImplicitEntityNameSource source) {
if ( source == null ) {
// should never happen, but to be defensive...
throw new HibernateException( "Entity naming information was not provided." );
}
String tableName = transformEntityName( source.getEntityNaming() );
if ( tableName == null ) {
throw new HibernateException( "Could not determine primary table name for entity" );
}
return toIdentifier( tableName, source.getBuildingContext() );
}
@Override
public Identifier determineJoinTableName(ImplicitJoinTableNameSource source) {
final String name = transformEntityName( source.getOwningEntityNaming() )
+ '_'
+ transformEntityName( source.getNonOwningEntityNaming());
return toIdentifier( name, source.getBuildingContext() );
}
@Override
public Identifier determineCollectionTableName(ImplicitCollectionTableNameSource source) {
final String entityName = transformEntityName( source.getOwningEntityNaming() );
final String name = entityName
+ '_'
+ transformAttributePath( source.getOwningAttributePath() );
return toIdentifier( name, source.getBuildingContext() );
}
@Override
public Identifier determineIdentifierColumnName(ImplicitIdentifierColumnNameSource source) {
return toIdentifier(
transformAttributePath( source.getIdentifierAttributePath() ),
source.getBuildingContext()
);
}
@Override
public Identifier determineDiscriminatorColumnName(ImplicitDiscriminatorColumnNameSource source) {
return toIdentifier(
source.getBuildingContext().getMappingDefaults().getImplicitDiscriminatorColumnName(),
source.getBuildingContext()
);
}
@Override
public Identifier determineTenantIdColumnName(ImplicitTenantIdColumnNameSource source) {
return toIdentifier(
source.getBuildingContext().getMappingDefaults().getImplicitTenantIdColumnName(),
source.getBuildingContext()
);
}
@Override
public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) {
String name = transformAttributePath( source.getAttributePath() );
name = addUnderscores(name);
return toIdentifier( name, source.getBuildingContext() );
}
@Override
public Identifier determineJoinColumnName(ImplicitJoinColumnNameSource source) {
// JPA states we should use the following as default:
//
// (1) if there is a "referencing relationship property":
// "The concatenation of the following: the name of the referencing relationship
// property or field of the referencing entity or embeddable class; "_"; the
// name of the referenced primary key column."
//
// (2) if there is no such "referencing relationship property", or if the association is
// an element collection:
// "The concatenation of the following: the name of the entity; "_"; the name of the
// referenced primary key column"
// todo : we need to better account for "referencing relationship property"
final String name;
//FIXME: This not handle manytomany relations. Doctrine using attribute name as reference column - Pavel Sokolov
/*
// For debug:
String soruceEntityName=source.getEntityNaming().getEntityName();
String sourceEntityColumn=source.getAttributePath().getProperty();
String referencedColumnName=source.getReferencedColumnName().getText();
ImplicitJoinColumnNameSource.Nature nature = source.getNature();
*/
if ( source.getNature() == ImplicitJoinColumnNameSource.Nature.ELEMENT_COLLECTION
|| source.getAttributePath() == null ) {
name = transformEntityName( source.getEntityNaming() )
+ '_'
+ source.getReferencedColumnName().getText();
}
else {
name = transformAttributePath( source.getAttributePath() )
+ '_'
+ source.getReferencedColumnName().getText();
}
return toIdentifier( name, source.getBuildingContext() );
}
@Override
public Identifier determinePrimaryKeyJoinColumnName(ImplicitPrimaryKeyJoinColumnNameSource source) {
// JPA states we should use the following as default:
// "the same name as the primary key column [of the referenced table]"
return source.getReferencedPrimaryKeyColumnName();
}
@Override
public Identifier determineAnyDiscriminatorColumnName(ImplicitAnyDiscriminatorColumnNameSource source) {
return toIdentifier(
transformAttributePath( source.getAttributePath() ) + "_" + source.getBuildingContext().getMappingDefaults().getImplicitDiscriminatorColumnName(),
source.getBuildingContext()
);
}
@Override
public Identifier determineAnyKeyColumnName(ImplicitAnyKeyColumnNameSource source) {
return toIdentifier(
transformAttributePath( source.getAttributePath() ) + "_" + source.getBuildingContext().getMappingDefaults().getImplicitIdColumnName(),
source.getBuildingContext()
);
}
@Override
public Identifier determineMapKeyColumnName(ImplicitMapKeyColumnNameSource source) {
return toIdentifier(
transformAttributePath( source.getPluralAttributePath() ) + "_KEY",
source.getBuildingContext()
);
}
@Override
public Identifier determineListIndexColumnName(ImplicitIndexColumnNameSource source) {
return toIdentifier(
transformAttributePath( source.getPluralAttributePath() ) + "_ORDER",
source.getBuildingContext()
);
}
@Override
public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {
return toIdentifier(
DoctrineNamingHelper.INSTANCE.generateHashedFkName(
"fk_",
source.getTableName(),
source.getReferencedTableName(),
source.getColumnNames()
),
source.getBuildingContext()
);
}
@Override
public Identifier determineUniqueKeyName(ImplicitUniqueKeyNameSource source) {
return toIdentifier(
DoctrineNamingHelper.INSTANCE.generateHashedConstraintName(
"uniq_",
source.getTableName(),
source.getColumnNames()
),
source.getBuildingContext()
);
}
@Override
public Identifier determineIndexName(ImplicitIndexNameSource source) {
return toIdentifier(
DoctrineNamingHelper.INSTANCE.generateHashedConstraintName(
"idx_",
source.getTableName(),
source.getColumnNames()
),
source.getBuildingContext()
);
}
protected Identifier toIdentifier(String stringForm, MetadataBuildingContext buildingContext) {
return buildingContext.getMetadataCollector()
.getDatabase()
.getJdbcEnvironment()
.getIdentifierHelper()
.toIdentifier( stringForm );
}
private String transformAttributePath(AttributePath attributePath) {
return addUnderscores(attributePath.getProperty());
}
protected String transformEntityName(EntityNaming entityNaming) {
String name=entityNaming.getEntityName();
name = StringHelper.unqualify( name );
name = addUnderscores(name);
return name;
}
protected static String addUnderscores(String name) {
final StringBuilder buf = new StringBuilder( name.replace('.', '_') );
for (int i=1; i<buf.length()-1; i++) {
if (
Character.isLowerCase( buf.charAt(i-1) ) &&
Character.isUpperCase( buf.charAt(i) ) &&
Character.isLowerCase( buf.charAt(i+1) )
) {
buf.insert(i++, '_');
}
}
return buf.toString().toLowerCase(Locale.ROOT);
}
}
答案 0 :(得分:0)
在这个游戏上有点晚了。我看到了5.4.6.Final的问题;似乎仍然是一个未解决的问题: