没有复合键的休眠中的多对多

Posted

技术标签:

【中文标题】没有复合键的休眠中的多对多【英文标题】:ManyToMany in Hibernate without composite keys 【发布时间】:2009-05-27 14:53:35 【问题描述】:

我正在处理遗留数据库。我正在使用 pojos & hibernate & HSQLDB 编写单元测试。我收到以下错误:

17:09:03,946 错误 SchemaExport:349 - 尝试在语句中定义第二个主键

假设我有PostTag 实体(当然还有他们的表poststags)。还有另一个表来定义PostTag 之间的多对多,称为post_tags

因为post_tags 包含一些关于关系的额外信息,例如activedeleted 列。我创建了另一个名为 PostTag 的实体来处理这个问题。

在这里描述我的问题是伪类:

@Entity
@Table(name="post_tags")
public class PostTag 
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @ManyToOne
    private Post post;

    @ManyToOne
    private Tag tag;

    // setters and getters


@Entity
@Table(name = "tags")
public class Tag 
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @ManyToMany(mappedBy = "tags",cascade = CascadeType.PERSIST, CascadeType.MERGE)
    private Set<Post> posts;

    // setters and getters


@Entity
@Table(name = "posts")
public class Post 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @ManyToMany
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    @JoinTable(name = "post_tags", joinColumns =  @JoinColumn(name = "post_id") , inverseJoinColumns =  @JoinColumn(name = "tag_id") )
    private Set<Tag> tags;

    // setters and getters

当我查看生成错误的语句时,似乎 Hibernate 正在尝试使用 PRIMARY KEY (post_id, tag_id) 生成复合键,并且它还试图生成 post_id identity

谁能帮我解决我的问题?

更新:

因为我正在处理旧数据库,所以这只是一个演示问题的示例。但是我会尽量按照例子翻译实际的语句(PS:不是ALTER TABLECREATE TABLE):

create table post_tags (id integer not null, post integer, tag integer, post_id integer generated by default as identity (start with 1), tag_id integer not null, primary key (post_id, tag_id)

【问题讨论】:

您也可以发布 ALTER TABLE 行吗?导致错误的那个? 【参考方案1】:

问题是PostTag 类中的@Id:它告诉hibernate 你想要一个生成的标识列。同时,你说的是“我想要一个复合键”与 Posts 类中的 tags 字段的映射。

你想要哪个? Hibernate 无法判断。

在“Java Persistence with Hibernate”一书的第 304 页上有一个很好的例子。 It's on Google books.

如果您不想要复合键,那么您必须将链接表视为真实对象并在Posts 类中使用PostTag(即Set&lt;PostTag&gt; postTags 而不是Set&lt;Tag&gt; tags

【讨论】:

好吧,我不想要复合键。如何在没有复合键的情况下进行多对多映射?

以上是关于没有复合键的休眠中的多对多的主要内容,如果未能解决你的问题,请参考以下文章

在休眠中的多对多映射中仅插入一个表

渴望加载 Laravel 5 与两个外键的多对多关系

如何在休眠/弹簧中更新多对多集合(延迟加载)?

Fluent NHibernate 多对多映射,使用自动生成的 pk 而不是复合键

如何删除与隐藏交集表的多对多关联中的记录?

如何使用 Doctrine 2 创建与额外字段的多对多自引用关联?