Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
314 views
in Technique[技术] by (71.8m points)

java - Ternary (and n-ary) relationships in Hibernate

Q 1) How can we model a ternary relationship using Hibernate? For example, how can we model the ternary relationship presented here using Hibernate (or JPA)?

NOTE: I know that JPA 2 has added some constructs for building ternary relationships using maps. However, this question assumes JPA 1 or Hibernate 3.3.x and I don't like to use maps to model this.

ER Model
(source: grussell.org)


ER Model with ternary relationships replaced
(source: grussell.org)

Ideally I prefer my model to be like this:

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

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

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

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

Q 1.1)

How can we model this variation, in which each Sale item might have many Products?

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

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

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

class Sale {
SalesAssistant soldBy;
Customer buyer;
Set<Product> products;
//...
}

Q 2) In general, how can we model n-ary, n >= 3 relationships with Hibernate?

Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Q1. How can we model a ternary relationship using Hibernate? For example, how can we model the ternary relationship presented here using Hibernate (or JPA)? (...)

I would remodel the association with an intermediate entity class (and that's the recommended way with Hibernate). Applied to your example:

@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. How can we model this variation, in which each Sale item might have many Products?

I wouldn't use a composite primary key here and introduce a PK for the Sale entity.

Q2. In general, how can we model n-ary, n >= 3 relationships with Hibernate?

I think that my answer to Q1. covers this. If it doesn't, please clarify.


Update: Answering comments from the OP

(...) the pk's fields are not getting populated and as a result I cannot save Sale items in the DB. Should I use setters like this for the Sale class? public void setBuyer(Customer cust) { this.buyer = cust; this.pk.buyerId = cust.getId(); }

You need to create a new Pk (I removed the constructors from my original answer for conciseness) and to set it on the Sale item. I would do something like this:

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);
...

And then persist the sale.

Also, in the JoinColumn annotations, what column are "name" fields referring to? The target relations' pks or the sale table's own column names?

To the columns for the attributes of the composite Pk (i.e. the sale table's own column names), we want them to get PK and FK constraints.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...