在为域类定义唯一约束时,grails为数据库生成一个基于属性名称的约束名称。 当使用Postgres作为数据库时,名称将是" unique_language'用于以下约束定义。
static constraints = {
language nullable: false, unique: 'product'
}
当我现在有第二个域类,它对具有相同名称的属性也有唯一约束时,grails将再次使用名称" unique_language'创建数据库约束。 问题是,对于Postgres,唯一约束的名称对于数据库模式也必须是唯一的。这意味着在我们的情况下,第二个 约束不适用于数据库。
有没有办法自定义或定义唯一索引名称?
我在寻找是否有可能增强NamingStrategy,但我无法找到改变的地方。
我们目前正在使用grails 2.4.4
答案 0 :(得分:1)
此问题已在Grails 3.1.0.RC2中修复:https://github.com/grails/grails-data-mapping/issues/623
答案 1 :(得分:1)
我们在我们的案例中使用grails 2.4.4,因此现在实现了一种解决方法。
我们实施了一种新的方言,它继承自班级org.hibernate.dialect.PostgreSQL9Dialect
。
新方言类中唯一的变化是分配一个名为PostgresUniqueDelegate
的自定义UnitqueDelegate。该类继承自org.hibernate.dialect.unique.DefaultUniqueDelegate
并覆盖约束生成的方法。
class PostgresSQL9DialectUniqueConstraints extends PostgreSQL9Dialect {
private final UniqueDelegate uniqueDelegate
PostgresSQL9DialectUniqueConstraints() {
super()
uniqueDelegate = new PostgresUniqueDelegate(this)
}
@Override
UniqueDelegate getUniqueDelegate() {
return uniqueDelegate
}
}
答案 2 :(得分:0)
以下是PostgresUniqueDelegate类的代码
class PostgresUniqueDelegate extends DefaultUniqueDelegate {
PostgresUniqueDelegate(Dialect dialect) {
super(dialect)
}
private final PREFIX = "unique_"
private String getCustomUniqueKey(String uniqueKeyName, String tableName) {
return uniqueKeyName.replaceAll(PREFIX, PREFIX + tableName + "_")
}
@Override
String getAlterTableToAddUniqueKeyCommand(
org.hibernate.mapping.UniqueKey uniqueKey,
String defaultCatalog,
String defaultSchema)
{
// Do this here, rather than allowing UniqueKey/Constraint to do it.
// We need full, simplified control over whether or not it happens.
final String tableName = uniqueKey.getTable().getQualifiedName(dialect, defaultCatalog, defaultSchema)
final String constraintName = dialect.quote(getCustomUniqueKey(uniqueKey.getName(), tableName))
return "alter table " + tableName + " add constraint " + constraintName + " " + uniqueConstraintSql(uniqueKey)
}
@Override
String getAlterTableToAddUniqueKeyCommand(UniqueKey uniqueKey) {
// Do this here, rather than allowing UniqueKey/Constraint to do it.
// We need full, simplified control over whether or not it happens.
final String tableName = uniqueKey.getTable().getQualifiedName(dialect)
final String constraintName = dialect.quote(getCustomUniqueKey(uniqueKey.getName(), tableName))
return "alter table " + tableName + " add constraint " + constraintName + uniqueConstraintSql(uniqueKey);
}
}