Hibernate JPA 2.0多对多和附加列
我试图在JPA2.0(JBoss 7.1.1)中建立一个多个关系,并在关系中增加一列(粗体,如下所示),如:Hibernate JPA 2.0多对多和附加列,hibernate,jakarta-ee,orm,jboss7.x,jpa-2.0,Hibernate,Jakarta Ee,Orm,Jboss7.x,Jpa 2.0,我试图在JPA2.0(JBoss 7.1.1)中建立一个多个关系,并在关系中增加一列(粗体,如下所示),如: Employer EmployerDeliveryAgent DeliveryAgent (id,...) (employer_id, deliveryAgent_id, **ref**) (id,...) 我不希望有重复的属性,因此我希望应用中介绍的第二个解决方案。但我无法让它工作,我会出现以下错误: 嵌入的ID类不应该包含关系映射(
Employer EmployerDeliveryAgent DeliveryAgent
(id,...) (employer_id, deliveryAgent_id, **ref**) (id,...)
我不希望有重复的属性,因此我希望应用中介绍的第二个解决方案。但我无法让它工作,我会出现以下错误:
Obs.:我没有在这里复制我的源代码,因为它本质上是上面链接中的源代码的副本,只是具有不同的类和属性名称,所以我想这是没有必要的。好的,我根据在 此解决方案不会在数据库上生成重复的属性,但会在我的JPA实体中生成重复的属性(这是非常可以接受的,因为您可以将额外的工作传递给构造函数或方法-它最终是透明的)。数据库中生成的主键和外键100%正确 如链接所述,我不能使用@PrimaryKeyJoinColumn,而是使用@JoinColumn(name=“projectId”,updateable=false,insertable=false,referencedColumnName=“id”)。另一件值得一提的事情是:我必须使用EntityManager.persist(association),链接中的示例中缺少了它 因此,我的最终解决方案是:
@Entity
public class Employee {
@Id
private long id;
...
@OneToMany(mappedBy="employee")
private List<ProjectAssociation> projects;
...
}
首先,您需要生成一个
EmployerDeliveryAgentPK
类,因为它有多个PK:
@Embeddable
public class EmployerDeliveryAgentPK implements Serializable {
@Column(name = "EMPLOYER_ID")
private Long employer_id;
@Column(name = "DELIVERY_AGENT_ID")
private Long deliveryAgent_id;
}
接下来,您需要创建一个EmployeerDeliveryAgent
类。此类表示雇主
和送货代理
之间的多对多关系:
@Entity
@Table(name = "EmployerDeliveryAgent")
public class EmployerDeliveryAgent implements Serializable {
@EmbeddedId
private EmployerDeliveryAgentPK id;
@ManyToOne
@MapsId("employer_id") //This is the name of attr in EmployerDeliveryAgentPK class
@JoinColumn(name = "EMPLOYER_ID")
private Employer employer;
@ManyToOne
@MapsId("deliveryAgent_id")
@JoinColumn(name = "DELIVERY_AGENT_ID")
private DeliveryAgent deliveryAgent;
}
之后,在Employer
类中,您需要添加:
@OneToMany(mappedBy = "deliveryAgent")
private Set<EmployerDeliveryAgent> employerDeliveryAgent = new HashSet<EmployerDeliveryAgent>();
@OneToMany(mappedBy = "employer")
private Set<EmployerDeliveryAgent> employer = new HashSet<EmployerDeliveryAgent>();
就这些!祝你好运 答案来自和帮助,但在关联表中使用ID是多余的。类中既有关联的实体,也有它们的ID。这不是必需的。您可以使用关联实体字段上的@Id
简单地映射关联类中的关联实体
@Entity
public class Employer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToMany(mappedBy = "employer")
private List<EmployerDeliveryAgent> deliveryAgentAssoc;
// other properties and getters and setters
}
@Entity
public class DeliveryAgent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToMany(mappedBy = "deliveryAgent")
private List<EmployerDeliveryAgent> employerAssoc;
// other properties and getters and setters
}
仍然需要关联PK类。请注意,字段名称应与关联类中的字段名称完全对应,但类型应为关联类型中id的类型
public class EmployerDeliveryAgentId implements Serializable {
private int employer;
private int deliveryAgent;
// getters/setters and most importantly equals() and hashCode()
}
非常感谢,我花了两天时间试图解决这个问题。我认为在
DeliveryAgent
类中,我们应该映射EmployeerDelivery
类,而不是Employeer
类。因此,DeliveryAgent
类中的代码应该类似于private-Set-employerDeliveryAgent=new-HashSet()代码>,与雇主
类中的代码相同。是否需要重写equals()
和hashcode()
?(假设我不打算将持久类的实例放在一个集合中,也不打算使用分离实例的重新附加)这是你能得到的最干净的解决方案,做得好。任何人都可以提供插入或删除示例。非常酷,谢谢。问题。。。如果我还将生成的@id列放入association类中(在您的示例中为EmployerDeliveryAgent),则会得到一个NPE。但是我想要一个RDBMS长PK。。。你说呢?有办法吗?拧上我的代理键?如何通过一个额外的字段id绑定实体,而不是布尔isProjectLead
?为什么需要id类?优雅的解决方案:
@OneToMany(mappedBy = "employer")
private Set<EmployerDeliveryAgent> employer = new HashSet<EmployerDeliveryAgent>();
@Entity
public class Employer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToMany(mappedBy = "employer")
private List<EmployerDeliveryAgent> deliveryAgentAssoc;
// other properties and getters and setters
}
@Entity
public class DeliveryAgent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToMany(mappedBy = "deliveryAgent")
private List<EmployerDeliveryAgent> employerAssoc;
// other properties and getters and setters
}
@Entity
@Table(name = "employer_delivery_agent")
@IdClass(EmployerDeliveryAgentId.class)
public class EmployerDeliveryAgent {
@Id
@ManyToOne
@JoinColumn(name = "employer_id", referencedColumnName = "id")
private Employer employer;
@Id
@ManyToOne
@JoinColumn(name = "delivery_agent_id", referencedColumnName = "id")
private DeliveryAgent deliveryAgent;
@Column(name = "is_project_lead")
private boolean isProjectLead;
}
public class EmployerDeliveryAgentId implements Serializable {
private int employer;
private int deliveryAgent;
// getters/setters and most importantly equals() and hashCode()
}