在使用hibernate和JPA的Spring MVC应用程序中,我正在尝试为其底层数据表具有两列主键的实体设置映射。 如何更改下面的代码才能使其正常工作?
我创建了一个名为conceptPK
的EmbeddedId,但是收到以下错误消息:
Caused by: org.hibernate.MappingException:
Unable to find column with logical name: conceptPK
in org.hibernate.mapping.Table(sct2_concept) and its related supertables and secondary tables
在实体类中,我使用以下代码设置主键:
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name="id", column=@Column(name="id")),
@AttributeOverride(name="effectiveTime", column=@Column(name="effectiveTime"))
})
private ConceptPK conceptPK;
嵌入式ConceptPK类如下:
@Embeddable
class ConceptPK implements Serializable {
@Column(name="id", nullable=false)
protected BigInteger id;
@Column(name="effectiveTime", nullable=false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime effectiveTime;
/** getters and setters **/
public DateTime getEffectiveTime(){return effectiveTime;}
public void setEffectiveTime(DateTime ad){effectiveTime=ad;}
public void setId(BigInteger id) {this.id = id;}
public BigInteger getId() {return id;}
}
为了便于阅读,我已将完整的代码和完整的堆栈跟踪上传到文件共享站点,而不是在此处创建过长的帖子。
您可以在文件共享网站by clicking on this link上阅读the class above
的完整代码。
您可以阅读引用第一个班级at this link的a second class
代码。
您可以阅读引用第一个班级at this link的a third class
代码。
您可以阅读创建基础数据表by clicking on this link的SQL code
。
您可以在文件共享网站by clicking on this link上阅读完整的堆栈跟踪。
答案 0 :(得分:1)
问题在于SnomedDescription
实体与@ManyToOne
的{{1}}关联。
首先,这不是ManyToOne,而是实际上是OneToOne,因为它们的主键是相同的。
但主要问题是您在此关联的SnomedConcept
注释中使用的列不作为数据库列存在,因此这将永远不会有效。
相反,您应该按如下方式加入列:
@JoinColumn
现在,你可以继续使用@ManyToOne
@JoinColumns({
@JoinColumn(name="id", referencedColumnName="id"),
@JoinColumn(name="effectiveTime", referencedColumnName="effectiveTime")
})
private SnomedConcept concept;
来建立这种关系,但实际上你应该为两者使用相同的嵌入式PK(@ManyToOne
),然后ConceptPK
看起来会更多像:
SnomedDescription
是的,您可以在多个实体中使用相同的PK嵌入式。
如果 是一对一的关系,那么@Entity
@Table(name = "accesslogs")
public class SnomedDescription {
@EmbeddedId
private ConceptPK descriptionPK;
@Column(name="active")
private boolean active;
@Column(name="moduleId")
private BigInteger moduleid;
@OneToOne
@PrimaryKeyJoinColumn
private SnomedConcept concept;
..... etc.
与SnomedConcept
之间的关联也应该是一对一的关联一个,SnomedDescription
。
如果两者之间的关联是可选的,那么始终存在的“边”应该将一对一定义为@PrimaryKeyJoinColumn
。换句话说,如果总是存在概念,但并不总是描述,那么概念中的一对一应该被定义为@OneToOne(optional=true)
。
答案 1 :(得分:0)
如下所示注释密钥解决了我的问题。
@Column(name = "name", nullable = false)
String name;