我有三个类,其中一个名称是User,这个用户有其他类实例。像这样;
public class User{
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
public List<APost> aPosts;
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
public List<BPost> bPosts;
}
public class BPost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
public class APost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
它的工作方式与此类似但在db中生成emty表。哪个必须包含外键。当我尝试使用mappedBy和JoinColumn annotains时,我失败了。我该如何解决这个问题?
额外信息:
当我改变时;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="id")
public User user;
和
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id")
public List<APost> aPosts;
我正在
发生JPA错误(无法构建EntityManagerFactory):实体映射中的重复列:models.post.APost列:id(应使用insert =“false”update =“false”映射)
最终编辑:最后,我对jpa注释完全错了。 :(当我改变
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id")
到
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
和
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="user_id")
everthing工作正常。 :)
答案 0 :(得分:64)
我不确定您的问题(“空表”等的含义,或mappedBy
和JoinColumn
无效的方式)。
我认为你试图建立双向关系。
首先,你需要决定哪一方“拥有”这种关系。 Hibernate将在这方面建立关系基础。例如,假设我让Post
方拥有关系(我正在简化你的例子,只是为了保持关键),映射将如下所示:
(希望语法正确。我只是通过记忆来写它们。但是这个想法应该没问题)
public class User{
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
private List<Post> posts;
}
public class Post {
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="user_id")
private User user;
}
通过这样做,Post
的表格将有一个存储关系的列user_id
。 Hibernate通过user
中的Post
来获取关系(而不是posts
中的User
。如果您有Post
的{{1}},您会注意到差异1}}但遗漏了user
的{{1}})。
您提到User
且posts
无效。但是,我相信这实际上是正确的方法。请告诉我这种方法是否适用于您,并提供有关该问题的更多信息。我认为这个问题是由于别的原因造成的。
编辑:
关于使用mappedBy
的一些额外信息,因为它通常会引起混淆。在JoinColumn
中,我们将“属性名称”放在双向关系的反面,而不是表列名。
答案 1 :(得分:27)
正如我在this article和我的书High-Performance Java Persistence中所解释的那样,你绝不应该使用单向@OneToMany
注释,因为:
现在,在您的第一个示例中,双方都拥有该关联,并this is bad。
虽然@JoinColumn
会让@OneToMany
方负责协会,但它绝对不是最佳选择。因此,请始终使用mappedBy
侧的@OneToMany
属性。
public class User{
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
public List<APost> aPosts;
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
public List<BPost> bPosts;
}
public class BPost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
public class APost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
答案 2 :(得分:-3)
由于您将直接保存APost和BPost,这意味着APost和BPost将成为关系所有者。由于用户不拥有该关系,因此@OneToMany注释中将存在属性mappedBy。
public class User{
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL,mappedBy="user", targetEntity = APost.class)
public List<APost> aPosts;
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL,mappedBy="user", targetEntity = BPost.class)
public List<BPost> bPosts;
}
public class BPost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="user_id",referencedColumnName="id")
public User user;
}
public class APost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="user_id",referencedColumnName="id")
public User user;
}
@JoinColumn注释将负责在Apost和BPost中添加外键。