这是正确的(更好的)对象关系映射吗?

我真的很难在我的项目中使用Hibernate。 我在这里描述的一些问题: Hibernate:得到太多行我开始想知道我的代码是否正确。 我正在开发一个庞大的项目,我不得不自己定义带注释的映射类。 但是当问题开始出现时,我决定重新创建与项目分开的数据库部分,并尝试在IDE中生成实体。

我有两个表: MyOptionMy有主键:列qwertypropertyPropertyOption表中的外键。 当然, Optionproperty作为主键。

在我的解决方案中,我创建了具有两个属性的@Embeddable MyPK类: String qwertyString property 。 在我的My实体中,我当然有@EmbeddedId MyPKproperty (与MyPK中的列名相同),但这是Option对象,而不是MyPK中的MyPK

 @ManyToOne @JoinColumn(name = "property", nullable = false, insertable = false, updatable = false) protected Option option; 

这是由Intellij Idea中的Hibernate Tools生成的实体。 没有EmbeddedId ,但有@IdClass 。 我认为@IdClass仅适用于基本类型。 但我有一个对象作为我的主键的一部分。 但是这里也有OptionEntity对象。 保持一列的基本类型和对象类型是否正确?

 @javax.persistence.IdClass(test.go.MyEntityPK.class) @javax.persistence.Table(name = "MY", schema = "PUBLIC", catalog = "PUBLIC") @Entity public class MyEntity { private String qwerty; @javax.persistence.Column(name = "QWERTY") @Id public String getQwerty() { return qwerty; } public void setQwerty(String qwerty) { this.qwerty = qwerty; } private String text; @javax.persistence.Column(name = "TEXT") @Basic public String getText() { return text; } public void setText(String text) { this.text = text; } private String lang; @javax.persistence.Column(name = "PROPERTY") @Id public String getProperty() { return property; } public void setProperty(String property) { this.property= property; } @Override public boolean equals(Object o) { //equals } @Override public int hashCode() { //hashCode } private OptionEntity optionByProperty; @ManyToOne @javax.persistence.JoinColumn(name = "PROPERTY", referencedColumnName = "PROPERTY", nullable = false) public OptionEntity getOptionByProperty() { return optionByProperty; } public void setOptionByProperty(OptionEntity optionByProperty) { this.optionByProperty = optionByProperty; } } 

这是MyEntityPK生成的类:

 public class MyEntityPK implements Serializable { private String qwerty; @Id @Column(name = "qwerty") public String getQwerty() { return qwerty; } public void setQwerty(String qwerty) { this.qwerty = qwerty; } private String property; @Id @Column(name = "PROPERTY") public String getProperty() { return property; } public void setProperty(String property) { this.property = property; } @Override public boolean equals(Object o) { //equals } @Override public int hashCode() { //hashCode } } 

OptionEntity如下。 此实体中没有特殊要点。 我想只对version属性上的@Version注释以及List而不是Collection

 @javax.persistence.Table(name = "OPTION", schema = "PUBLIC", catalog = "PUBLIC") @Entity public class OptionEntity { private Long version; @javax.persistence.Column(name = "VERSION") @Basic public Long getVersion() { return version; } public void setVersion(Long version) { this.version = version; } private String property; @javax.persistence.Column(name = "PROPERTY") @Id public String getProperty() { return property; } public void setProperty(String property) { this.property = property; } @Override public boolean equals(Object o) { //equals } @Override public int hashCode() { //hashcode } private Collection myByProperty; @OneToMany(mappedBy = "optionByProperty") public Collection getMyByProperty() { return myByProperty; } public void setMyByProperty(Collection myByProperty) { this.myByProperty = myByProperty; } } 

什么选择最合适,问题最少? 我描述的那个还是粘贴的那个?

摆脱财产private String lang; / private String property; 它已经由多人定义。 你也不需要MyEntity主键的类。 MyEntity可以是它自己的id类,它有两个属性qwertyoption作为它的key-property,key-manytoone。

查看使用派生ID的JPA 2.0示例: http : //wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/DerivedIdentifiers ,它们似乎就是您所追求的。

在JPA中,你的id不需要embeddedId,但是如果使用复合PK,你需要一个类来保存构成pk的多个值。 此类的实例将传递给em.find方法,它可以是EmbeddedId或PKClass。 我更喜欢自己使用PKClass,但它取决于你 – 使用嵌入式只是将字段放在可嵌入类中,因此您使用嵌入对象来设置映射并访问值。 如果使用pkClass,则不需要在其中注释的字段/属性,因为它们是直接在实体中访问和映射的。