休眠验证错误的实体外键
当Hibernate的EntityManager启动并验证实体映射时,我遇到了一个问题。在我可以起草简单的说,我有以下四类:休眠验证错误的实体外键
@Entity
@Table(name="abc_rule")
public class Rule {
@Id
@Column(name="id")
private Integer id;
@ManyToOne
private RuleType ruleType;
}
@Entity
@Table(name="abc_rule_type")
@IdClass(RuleTypeKey.class)
public class RuleType {
@Id
private String typeCode;
@Id
private String otherCode;
@Column(name="descr")
private String description;
}
public class RuleTypeKey {
@Id
@Column(name="type_cd")
private String typeCode;
@Id
@Column(name="other_cd")
private String otherCode;
}
@Entity
@Table(name="abc_rule_type")
public class RuleTypeSimple {
@Id
@Column(name="id")
private Integer id;
@Column(name="type_cd")
private String typeCode;
@Column(name="other_cd")
private String otherCode;
@Column(name="descr")
private String description;
}
当Hibernate启动时,我得到以下异常:
外键(FK4AD4C4B924F958E2:abc_rule [ruleType_type_cd,ruleType_other_cd ]))必须具有相同数目的列 作为引用的主键的(abc_rule_type [ID])
如果我暂时上重命名@Table注解为"abc_rule_type_123"
然后Hibernate验证并按预期使用映射。对我来说,这看起来像Hibernate正在验证基于表名称的外键映射,而不是被引用的实际类的设置。
有没有明显的东西我缺少这将迫使Hibernate基于类验证?或者让它甚至不验证外键,并相信我做对了?
作为一个方面说明,我知道有两个不同的标识符设置映射两次类的好理由。在我的情况下,它导致两个不同的代码项目在相同的数据库上合并。一种以只读方式使用,因此可以避开这种不寻常的映射。不幸的是,两个代码库都有相当数量的代码包装在他们的类的版本中,重构将是一个很大的工作,我希望现在可以避免。
请记住,Hibernate是一个ORM工具,所以您应该尝试遵循一些OOP规则或最佳实践来利用它。
使用几列作为主键根本不应该完成,如果你完全*做(如果有人会杀了你,如果你不这样做,或者你有一个古老的关系数据库已经创建并且超出了你的人的范围),那么你应该使用带有@EmbeddedId注释的@Embedable Id,并且也不会使用@Id注释注释每一列。
下面是一个EmbeddedId例如:EmbeddedCompoundPrimaryKey Example
同时,我不知道什么是你要创建的模型(如果你至少发布图表或表格脚本它将帮助),但与此更正它不应该给你更多的错误:
@Entity
@Table(name="abc_rule")
public class Rule {
@Id
@Column(name="id")
private Integer id;
@ManyToOne
private RuleType ruleType;
}
@Entity
@Table(name="abc_rule_type")
//@IdClass(RuleTypeKey.class) <--I don't think this is right
public class RuleType {
@EmbeddedId //Add this
private RuleTypeKey id; //And this
/* Remove this
@Id
private String typeCode;
@Id
private String otherCode;*/
@Column(name="descr")
private String description;
}
@Embeddable //Add this
public class RuleTypeKey {
//@Id <--remove this
@Column(name="type_cd")
private String typeCode;
//@Id <--remove this
@Column(name="other_cd")
private String otherCode;
}
@Entity
//@Table(name="abc_rule_type") <--must be different table name
@Table(name="abc_rule_type_simple")
public class RuleTypeSimple {
@Id
@Column(name="id")
private Integer id;
@Column(name="type_cd") //Are this two colums a reference to
private String typeCode; //The RuleType too?? if so the must be
//The same as in class Rule (ManyToOne)
@Column(name="other_cd")
private String otherCode;
@Column(name="descr")
private String description;
}
尝试,让我知道,如果它的工作原理(这可能有几个sintax错误,检查它)
不幸的是,休眠期间外国投完全相同的例外使用EmbeddedId时进行密钥验证战略研究。 – 2012-08-09 15:00:25
请检查编辑后的回复,我举了一个如何实现类的例子(尽管这有助于理解你到底想要建模什么) – 2012-08-09 23:34:43