这是正确的(更好的)对象关系映射吗?
我真的很难在我的项目中使用Hibernate。 我在这里描述的一些问题: Hibernate:得到太多行我开始想知道我的代码是否正确。 我正在开发一个庞大的项目,我不得不自己定义带注释的映射类。 但是当问题开始出现时,我决定重新创建与项目分开的数据库部分,并尝试在IDE中生成实体。
我有两个表: My
和Option
。 My
有主键:列qwerty
和property
。 Property
是Option
表中的外键。 当然, Option
将property
作为主键。
在我的解决方案中,我创建了具有两个属性的@Embeddable
MyPK
类: String qwerty
和String property
。 在我的My
实体中,我当然有@EmbeddedId
MyPK
和property
(与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类,它有两个属性qwerty
和option
作为它的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,则不需要在其中注释的字段/属性,因为它们是直接在实体中访问和映射的。