好的,我根据提供的解决方案让它工作了
http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Mapping_a_Join_Table_with_Additional_Columns.
此解决方案不会在数据库上生成重复的属性,但它会在我的 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;
...
// Add an employee to the project.
// Create an association object for the relationship and set its data.
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);
// Also add the association object to the employee.
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;
}
}