【问题标题】:Hibernate is generating the same foreign key constraint multiple times with inheritance strategy SINGLE_TABLEHibernate 使用继承策略 SINGLE_TABLE 多次生成相同的外键约束
【发布时间】:2013-10-09 20:01:00
【问题描述】:

我正在对两种类型的变量进行建模,分别称为AVar 和BVar。它们每个都可以与多个值相关联,类型分别为AValue 和BValue。我决定使用继承,这样每个具体类都继承自一个抽象基类(变量或值)。

然后我有一个从抽象值到抽象变量的多对一映射。对于变量,我使用SINGLE_TABLE 继承。对于价值,我使用TABLE_PER_CLASS 继承。 Hibernate 支持所有这些并且可以很好地生成表,但是,我得到相同的外键约束 3 次,这是双重冗余的。是我的设置有问题,还是 Hibernate 错误?

Hibernate 模式更新的输出:

HHH000262: Table not found: dm_variables
HHH000262: Table not found: dm_variables_a_values
HHH000262: Table not found: dm_variables_b_values

create table dm_variables (type varchar(31) not null, id varchar(36) not null, version bigint not null, name varchar(255) not null, variable_set_id varchar(36) not null, primary key (id), unique (variable_set_id, name))
create table dm_variables_a_values (id varchar(36) not null, version bigint not null, [current] bit not null, variable_id varchar(36) not null, member_id int, primary key (id))
create table dm_variables_b_values (id varchar(36) not null, version bigint not null, [current] bit not null, variable_id varchar(36) not null, string_value varchar(255), primary key (id))

alter table dm_variables_a_values add constraint FK__dm_values__variable_id90d2dd34 foreign key (variable_id) references dm_variables
alter table dm_variables_a_values add constraint FK7ED02C351F5CFA0E90d2dd34 foreign key (variable_id) references dm_variables
alter table dm_variables_a_values add constraint FK7ED02C35F9E9BFC090d2dd34 foreign key (variable_id) references dm_variables
alter table dm_variables_b_values add constraint FK__dm_values__variable_id5135dfd4 foreign key (variable_id) references dm_variables
alter table dm_variables_b_values add constraint FK7ED02C351F5CFA0E5135dfd4 foreign key (variable_id) references dm_variables
alter table dm_variables_b_values add constraint FK7ED02C35F9E9BFC05135dfd4 foreign key (variable_id) references dm_variables

HHH000232: Schema update complete

代码(简化):

@Entity
@Table(name = "dm_variables")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class Variable extends BaseEntity {
}

@Entity
@DiscriminatorValue(value = "A")
public class AVar extends Variable {
}

@Entity
@DiscriminatorValue(value = "B")
public class BVar extends Variable {
}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Value extends BaseEntity {

    @ManyToOne
    @JoinColumn(name = "variable_id", nullable = false)
    @ForeignKey(name = "FK__dm_values__variable_id")
    private Variable variable;
}

@Entity
@Table(name = "dm_variables_a_values")
public class ValueA extends Value {
}

@Entity
@Table(name = "dm_variables_b_values")
public class ValueB extends Value {
}

【问题讨论】:

  • 架构更新后,dm_variables_a_values 中有多少个约束?
  • 我得到 3 个约束说同样的话。 “外键 (variable_id) 引用 dm_variables”。您可以在原始问题中的 Hibernate 输出中看到这一点。
  • 您发布的是架构更新脚本,我只是想知道这 3 个约束是否是在脚本执行之后创建的。
  • 尝试插入违反约束的行时有什么信息? (您必须有一个 ConstraintViolationException,但是异常消息中显示的约束名称是什么?)
  • 我明白你的意思。是的,所有 6 个约束都已创建。这是在 SQL Server 中,我猜它允许这样的冗余约束。我收到的消息是“INSERT 语句与 FOREIGN KEY 约束“FK__dm_values__variable_id90d2dd34”冲突。冲突发生在数据库“”、表“dbo.dm_variables”、“id”列中。”

标签: java hibernate inheritance


【解决方案1】:

我不认为这真的是一个错误。我同意这不是最优的,但这种行为不会产生太多后果。特别是:

  • 约束冲突错误消息包含您使用@Constraint 指定的约束名称
  • 我们可以预期,在运行时,会按顺序评估约束,一旦违反一个约束,就不会评估另一个约束。

此外,shema-update 功能不是框架的核心功能(即使它被广泛使用且功能强大),我认为这种行为不会破坏 schema-update合同。在我看来,这可能是一个小小的改进。

【讨论】:

  • 我最终发现这种关系对于我的具体业务案例来说并不十分准确。修改它删除了这种行为。你是对的,它是无害的,但是,我仍然认为它是一个错误。 :)
猜你喜欢
  • 1970-01-01
  • 2011-09-27
  • 1970-01-01
  • 2016-08-14
  • 2012-02-24
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多