2010-04-10 82 views
6

问1)我们如何使用Hibernate建立三元关系模型?例如,我们如何使用Hibernate(或JPA)建模呈现here的三元关系?Hibernate中的三元关系

注意:我知道JPA 2已​​经添加了一些构建用于使用地图建立三元关系。然而,这个问题假设JPA 1或Hibernate 3.3.x,我不喜欢用地图来模拟这个。

ER Model http://db.grussell.org/co22001%20notes_files/image043.gif


ER Model with ternary relationships replaced http://db.grussell.org/co22001%20notes_files/image045.gif

理想我宁愿我的模型是这样的:

class SaleAssistant { 
Long id; 
//... 
} 

class Customer { 
Long id; 
//... 
} 

class Product { 
Long id; 
//... 
} 

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

Q 1.1)

我们怎么可以这样变化,模型,其中每个销售项目可能有多个产品? 2)一般情况下,我们如何建模n元组,n = 3与Hibernate的关系?

在此先感谢。

回答

11

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实体引入PK。第二季度销售价格指数为:

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

我认为我的答案是Q1。涵盖这一点。如果没有,请澄清。


更新:从没有得到填充PK的领域OP

(......),因此我无法保存在数据库销售项目回答评论。我应该在销售类中使用这样的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约束。

+0

谢谢你的回应。但是当我使用这个时遇到问题:pk的字段没有被填充,因此我无法将销售项目保存在数据库中。 我应该如何使用这样的销售类的setter? public void setBuyer(Customer cust){this.buyer = cust; this.pk.buyerId = cust.getId(); } 此外,在JoinColumn注释中,哪些列是“名称”字段引用的?目标关系'pks或销售表的自己的列名称? – Behrang 2010-04-11 02:00:34

0

您是否在使用数据库生成的Customer,Product和SalesAssistant主键?这可能会导致问题,因为它看起来像你试图使用实际的数据库身份,而不是让Hibernate在实际持久化过程中解析对象引用。

上面的嵌入式PK对我来说看起来很奇怪,但我没有机会尝试一下。看起来这些列是重叠的,并且互相破坏。

我认为只要有ManyToOne引用就足够了。

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