好的,根据此处提供的解决方案,我已经使其运作。
这个解决方案不会在数据库中生成重复的属性,但是却会在我的JPA实体中生成重复的属性(这很可接受,因为您可以将额外的工作转移给构造函数或方法 - 这最终会变得透明)。 数据库中生成的主键和外键是100%正确的。
正如链接中所述,我无法使用@PrimaryKeyJoinColumn,而是使用了@ JoinColumn(name =“projectId”,updatable = false,insertable = false,referencedColumnName =“id”)。 还有一件值得一提的事情:我必须使用EntityManager.persist(association),这在链接示例中是缺失的。
因此,我的最终解决方案是:
@Entity
public class Employee {
@Id
private long id;
...
@OneToMany(mappedBy="employee")
private List<ProjectAssociation> projects;
...
}
@Entity
public class Project {
@PersistenceContext
EntityManager em;
@Id
private long id;
...
@OneToMany(mappedBy="project")
private List<ProjectAssociation> employees;
...
public void addEmployee(Employee employee, boolean teamLead) {
ProjectAssociation association = new ProjectAssociation();
association.setEmployee(employee);
association.setProject(this);
association.setEmployeeId(employee.getId());
association.setProjectId(this.getId());
association.setIsTeamLead(teamLead);
em.persist(association);
this.employees.add(association);
employee.getProjects().add(association);
}
}
@Entity
@Table(name="PROJ_EMP")
@IdClass(ProjectAssociationId.class)
public class ProjectAssociation {
@Id
private long employeeId;
@Id
private long projectId;
@Column(name="IS_PROJECT_LEAD")
private boolean isProjectLead;
@ManyToOne
@JoinColumn(name = "employeeId", updatable = false, insertable = false,
referencedColumnName = "id")
private Employee employee;
@ManyToOne
@JoinColumn(name = "projectId", updatable = false, insertable = false,
referencedColumnName = "id")
private Project project;
...
}
public class ProjectAssociationId implements Serializable {
private long employeeId;
private long projectId;
...
public int hashCode() {
return (int)(employeeId + projectId);
}
public boolean equals(Object object) {
if (object instanceof ProjectAssociationId) {
ProjectAssociationId otherId = (ProjectAssociationId) object;
return (otherId.employeeId == this.employeeId)
&& (otherId.projectId == this.projectId);
}
return false;
}
}