【发布时间】:2017-08-16 18:39:01
【问题描述】:
我使用 jpa 和 hibernate 作为 jpa 提供者。
在 jpa 中学习了复合主键概念后,我正在尝试使用 @IdClass 注释来实现。
我创建了一个 Project.java ,在这里我想使用 deptId 和 projectId 作为我的复合键。
所以根据互联网上提到的概念,我将 deptId 和 projectId 保存到 ProjectID.class 中
请看下面的 ProjectID.java
public class ProjectID implements Serializable {
private String deptId;
private String projectId;
public ProjectID()
{
}
@Override
public int hashCode()
{
int result=1;
int prime=31;
result = prime*result + ((deptId==null) ? 0 : deptId.hashCode());
result = result + (prime*result + ((projectId==null) ? 0 : projectId.hashCode()));
return result;
}
@Override
public boolean equals(Object obj)
{
if(this==obj)
return true;
if(obj==null) return false;
if(this.getClass() != obj.getClass())
return false;
ProjectID pId = (ProjectID)obj;
if(deptId==null)
if(pId.deptId!=null)
return false;
if(projectId==null)
if(pId.projectId!=null)
return false;
return true;
}
public String getDeptId() {
return deptId;
}
public void setDeptId(String deptId) {
this.deptId = deptId;
}
public String getProjectId() {
return projectId;
}
public void setProjectId(String projectId) {
this.projectId = projectId;
}
}
如你所见,我已经实现了 Serializable 接口、equals 和 hashcode 方法。
现在看看 Project.java
@Entity
@IdClass(entity.beans.ProjectID.class)
public class Project {
@Id
private String deptId;
@Id
private String projectId;
private String name;
public ProjectID getPid() {
return pid;
}
public void setPid(ProjectID pid) {
this.pid = pid;
}
private String manager;
private ProjectID pid;
private int headCount;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getManager() {
return manager;
}
public void setManager(String manager) {
this.manager = manager;
}
public int getHeadCount() {
return headCount;
}
public void setHeadCount(int headCount) {
this.headCount = headCount;
}
}
现在这是一块,我不确定。请告诉我这是否正确。
我正在使用以下类来持久化项目实体。
public class DemoProject {
EntityManagerFactory emf;
EntityManager manager;
String persistenceUnitName="chapter.three";
DemoProject()
{
emf = Persistence.createEntityManagerFactory(persistenceUnitName);
manager = emf.createEntityManager();
}
public void runTheShow()
{
manager.getTransaction().begin();
ProjectID id = new ProjectID();
id.setDeptId("QA");
id.setProjectId("Auto");
Project p1 = new Project();
p1.setName("World Bank");
p1.setHeadCount(26);
p1.setManager("Mr.Ashish");
p1.setPid(id);
manager.persist(p1);
manager.getTransaction().commit();
manager.close();
emf.close();
}
public static void main(String args[])
{
DemoProject ob = new DemoProject();
ob.runTheShow();
}
}
在执行上述代码时,我无法初始化@Id 注释标记的字段。我收到错误为“ORA-01400:无法将 NULL 插入(“SYSTEM”。“PROJECT”。“DEPTID”)”
我需要帮助才能通过 jpa 注释正确配置复合键。
问候, 灰烬
【问题讨论】:
-
是否有理由使用复合键(例如遗留代码)?如果没有,我的建议是远离!
-
好吧,你永远不会初始化这些字段。所以他们是空的。而且您不应该在实体中具有 pid 属性,因为您已经拥有 projectId 和 deptId。这已记录在案,例如:docs.jboss.org/hibernate/orm/current/userguide/html_single/…。 +1 到 StuPointerException。坚持使用单列、纯技术、自动生成的 ID。
-
@StuPointerException 我理解你的观点,但我正在为 JPA 认证做准备,我期待对此提出问题。
-
@JBNizet 我将通过你给出的例子。谢谢大家!。
标签: jpa composite-id