简体   繁体   中英

JPA/Hibernate: Map many-to-many relationship when join table has own primary key

I have three tables with simple structure:

pub [id, name]
days [id, name]
pub_days [id, pub_id, days_id]

For some unholy reason, somebody thought that compound identity for pub_days table (that would be pub_id + days_id) is not enough and added own primary key. I can't change it now, other and larger system depends on that. #sigh

I am trying to map this to Hibernate with standard @ManyToMany JPA annotation like so (I omitted getters, setters, @Entitiy annotations and other clutter):

class Pub {

    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(name = "pub_days",
            joinColumns = {@JoinColumn(name = "pub_id")},
            inverseJoinColumns = {@JoinColumn(name = "days_id")})
    @OrderBy("id")
    private List<Day> pubOpeningDays;
}

class Day {
    @Id Long id;
    String name.
}

when I execute following code:

Day day = repository.find(Day.class, id);
pub.getPubOpeningDays().add(day);
repository.persist(pub);

I get this error:

ERROR: ORA-01400: cannot insert NULL into ("PUB"."pub_days"."id")

Sadly, that makes perfect sense, because I haven't mapped that ID anywhere. The thing is, I don't even want to. I want it to be generated, but not sure how do I overcome this issue with @ManyToMany mapping. Any ideas?

I only see two choices, either you change your mapping to a list of PubDay as samwise-gamgee told you in the comments or you add a trigger on insert on table pub_days which set a value for the column id if it is null (it could be using a sequence). But this approach depends on the features supported by your DB.

你可以做的就像我在评论中提到的那样你可以创建一个单独的实体CD,它将依次连接两个A和B类,现在A和B之间的关系将是多对多,因此A(多对多) CD(多对多)B。现在根据您的要求,无论何时需要获取A或B的实例,您可以做的只是使用适当的参数在DB中触发查询,即id的id或id为b帮助您获得所需的结果。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM