Hibernate 中的 ManyToMany 没有复合键
我正在处理遗留数据库。 我正在使用 pojos & 编写单元测试 休眠和 HSQLDB。 我收到以下错误:
17:09:03,946 ERROR SchemaExport:349 - Attempt to define a second primary key in statement
假设我有 Post
和 Tag
实体(当然还有它们的表 posts
和 tags< /代码>)。 还有另一个表用于定义
Post
和 Tag
之间的多对多,称为 post_tags
。
因为 post_tags
包含一些有关关系的额外信息,例如 active
和 deleted
列。 我创建了另一个名为 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
身份
。
谁能帮我解决我的问题吗?
更新:
因为我正在处理遗留数据库,这只是一个演示问题的示例。 但我会尝试根据示例翻译实际语句(PS:它不是 ALTER TABLE
它是 CREATE 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)
I am dealing with legacy database. And I am writing unit test using pojos & hibernate & HSQLDB. And I am getting the following error:
17:09:03,946 ERROR SchemaExport:349 - Attempt to define a second primary key in statement
Let's say I have Post
and Tag
entities (and of course their tables posts
and tags
). And there is another table to define many-to-many between Post
and Tag
called post_tags
.
Because post_tags
contains some extra information about the relation, like active
and deleted
columns. I created another Entity called PostTag
to handle this.
To describe my problem here are the pseudo classes:
@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
}
When I look at the statement that generates the error it seems Hibernate is trying to make a composite key using PRIMARY KEY (post_id, tag_id)
, and also it tries to make post_id
identity
.
Can anyone help me to fix my problem?
UPDATE:
Because I am dealing with a legacy database this was just an example to demonstrate the problem. But I will try to translate the actual statement according to the example (PS: It is not ALTER TABLE
it is a CREATE 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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是类
PostTag
中的@Id:它告诉hibernate你想要一个生成的标识列。 同时,您可以通过Posts
类中tags
字段的映射来表示“我想要一个复合键”。你想要哪一个? 休眠无法判断。
《Java Persistence with Hibernate》一书中的第304页有一个非常好的例子。 它在 Google 图书上。
如果您不需要复合键,则必须将链接表视为真实对象,并在
Posts
类中使用PostTag
(即Set) postTags
而不是Set标签
)The problem is the @Id in the class
PostTag
: It tells hibernate that you want a generated identity colum. At the same time, you're saying "I want a composite key" with the mapping of thetags
field in the classPosts
.Which one do you want? Hibernate can't tell.
There is a very good example on page 304 in the book "Java Persistence with Hibernate". It's on Google books.
If you don't want the composite key, then you must treat the link table as real objects and use
PostTag
in the classPosts
(i.e.Set<PostTag> postTags
instead ofSet<Tag> tags
)