[英]Classes Relationships with JPA
我有一组具有以下UML图的Java类:
public class Invoice {
@Id
private long id;
...
}
public class InvoiceDetail {
@Id
private long id;
...
private String productName;
private int quantity;
private double price;
}
我的目的是使用JPA批注在它们之间建立不同的关系。 Invoice和InvoiceDetail之间存在组成关系,可以分别使用@Embedded和@Embeddable批注分别解决 Invoice和InvoiceDetail的组成关系。 但是,通过建立InvoiceDetail,Class3和Class4之间的关系会出现问题。 在这些关系中,InvoiceDetail必须注释为@Entity。 但是,如果在与@Entity和@Embeddable同时注释一个类时,则相应的服务器将在部署期间引发运行时错误。 根据本网站的信息,我编写了以下可能的解决方案:
@Entity
public class Invoice {
@Id
private long id;
...
@ElementCollection
@CollectionTable(name="INVOICEDETAIL", joinColumns=@JoinColumn(name="INVOICE_ID"))
private List<InvoiceDetail> invoiceDetails;
...
}
为了解决我的问题,这是正确的吗?
提前致谢。
尽管很难知道这些类的真正含义,但是我认为您有一个设计问题。 Class1和Class2之间的组合表明,任何Class2实例仅存在于相应Class1实例的生命周期内。 但是另一方面,您具有Class3实例和Class4实例,它们可以/必须与Class2实例具有关系。
我要说的是,从我的角度来看,Class1和Class2之间的关系应该是简单的关联,而不是组成。 遵循此路径,Class2将成为JPA中的一个Entity,那么您应该已解决了问题。
我通常将@Embeddable用于实例自身不存在的类,并将@Entity用于其实例可以不存在其他实例的任何类。 例如,可以以任何一种方式实现地址,但不能在同一系统上实现。 如果我不想链接地址,则地址为@Embeddable,但如果我想确保同一地址没有保存在多行中,则地址必须为@Entity。
[编辑:在第1类和第2类重命名为Invoice和InvoiceDetails之后添加]
在Invoice和InvoiceDetails之间有一个组合很有意义。 但是我仍然认为您应该避免InvoiceDetails具有双重性格。 我可以想到两种解决方案(两种重构):
我检查了JPA应用程序,未发现@Entity和@Embeddable属于同一类。 老实说,我怀疑这是否有可能,因为@Embeddable的官方javadoc说:
指定一个类,其实例存储为拥有实体的固有部分并共享该实体的标识 。
由于@Entity具有自己的身份,因此您将尝试声明具有两个身份的同一对象-这是行不通的。
[/编辑]
[edit2:为解决方案建议2添加代码]
该代码应在某些假设下工作(请参见下文)。 这是针对1:n关系的双向导航的实现。
@Entity
public class Invoice {
@Id
private long id;
@OneToMany(mappedBy="invoice", cascade = CascadeType.ALL)
private List<InvoiceDetail> details;
}
@Entity
public class InvoiceDetails {
@Id
private long id;
@ManyToOne
@JoinColumn(name="invoice_id")
private Invoice invoice;
}
假设:表的命名方式与实体相同,invoice_details表的外键列的名称为“ invoice_id”,两个表的主键列的名称均为“ id”。 请注意,mappedBy值“发票”是指实体字段,而名称值“ invoice_id”是指数据库表。 删除仍由您的Class3或Class4实例引用其InvoiceDetails的Invoice对象时要小心-您必须首先释放这些引用。
有关JPA的信息,请参考以下资源:
[/编辑]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.