Hibernate中的三元(和n-ary)关系

问1)我们如何使用Hibernate建模三元关系? 例如,我们如何使用Hibernate(或JPA)对这里呈现的三元关系进行建模?

注意 :我知道JPA 2添加了一些用于使用地图构建三元关系的构造。 但是,这个问题假设JPA 1或Hibernate 3.3.x并且我不喜欢使用map来对此进行建模。

ER模型http://sofzh.miximages.com/java/image043.gif


替代三元关系的ER模型http://sofzh.miximages.com/java/image045.gif

理想情况下,我更喜欢我的模型:

class SaleAssistant { Long id; //... } class Customer { Long id; //... } class Product { Long id; //... } class Sale { SalesAssistant soldBy; Customer buyer; Product product; //... } 

问1.1)

我们如何对这种变化进行建模,其中每个Sale项目可能包含许多产品?

 class SaleAssistant { Long id; //... } class Customer { Long id; //... } class Product { Long id; //... } class Sale { SalesAssistant soldBy; Customer buyer; Set products; //... } 

问2)一般来说,我们如何用Hibernate建模n-ary,n> = 3的关系?

提前致谢。

Q1。 我们如何使用Hibernate建模三元关系? 例如,我们如何使用Hibernate(或JPA)对这里呈现的三元关系进行建模? (……)

我会改造与中间实体类的关联(这是Hibernate的推荐方法)。 适用于您的示例:

 @Entity public class Sale { @Embeddable public static class Pk implements Serializable { @Column(nullable = false, updatable = false) private Long soldById; @Column(nullable = false, updatable = false) private Long buyerId; @Column(nullable = false, updatable = false) private Long productId; public Pk() {} public Pk(Long soldById, Long buyerId, Long productId) { ... } // getters, setters, equals, hashCode } @EmbeddedId private Pk pk; @ManyToOne @JoinColumn(name = "SOLDBYID", insertable = false, updatable = false) private SaleAssistant soldBy; @ManyToOne @JoinColumn(name = "BUYERID", insertable = false, updatable = false) private Customer buyer; @ManyToOne @JoinColumn(name = "PRODUCTID", insertable = false, updatable = false) private Product product; // getters, setters, equals, hashCode } 

Q1.1。 我们如何对这种变化进行建模,其中每个Sale项目可能包含许多产品?

我不会在这里使用复合主键并为Sale实体引入PK。

Q2。 一般来说,我们如何用Hibernate建模n-ary,n> = 3的关系?

我认为我对Q1的回答。 涵盖了这个。 如果没有,请澄清。


更新:回答OP的评论

(…)pk的字段没有填充,因此我无法在DB中保存Sale项目。 我应该在Sale类中使用这样的setter吗? public void setBuyer(Customer cust){this.buyer = cust; this.pk.buyerId = cust.getId(); }

您需要创建一个新的Pk (我从原始答案中删除了构造函数以获得简洁性)并将其设置在Sale项目上。 我会做这样的事情:

 Sale sale = new Sale(); Pk pk = new Pk(saleAssistant.getId(), customer.getId(), product.getId()); sale.setPk(pk); sale.setSoldBy(saleAssistant); sale.setBuyer(customer); sale.setProduct(product); ... 

然后坚持sale

另外,在JoinColumn注释中,哪个列是“name”字段引用? 目标关系’pks或销售表自己的列名?

对于复合Pk属性的列(即销售表自己的列名),我们希望它们获得PK 和FK约束。

您是否为Customer,Product和SalesAssistant使用数据库生成的主键? 这可能会导致问题,因为看起来您正在尝试使用实际的数据库身份,而不是让Hibernate在实际持久性期间解析对象引用。

以上嵌入式PK对我个人来说很奇怪,但我没有机会尝试一下。 看起来这些列是重叠的,彼此相互冲突。

我认为只需拥有ManyToOne参考就足够了。

此外,打开SQL语句调试并查看发送到数据库的内容。