JPA OneToMany和ManyToOne关系
我有三个类的名称是用户和这个用户有其他类的实例。 喜欢这个;
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; }
它是这样的工作,但在数据库中生成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错误(无法构buildEntityManagerFactory):实体映射中的重复列:models.post.APost column: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工作正常。 🙂
正如我在本文和我的书“ 高性能Java持久性”中所解释的 ,您不应该使用单向的@OneToMany
注释,因为:
- 它会生成低效的SQL语句
- 它会创build一个额外的表,这会增加数据库索引的内存占用量
现在,在你的第一个例子中,双方都拥有这个协会, 这是不好的 。
虽然@JoinColumn
会让@OneToMany
方负责关联,但绝对不是最好的select。 因此,请始终使用@OneToMany
一侧的mappedBy
属性。
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; }
我真的不知道你的问题(“空表”的含义,或如何mappedBy
和JoinColumn
不工作)。
我想你是在尝试做一个双向的关系。
首先,你需要决定哪一方“拥有”这种关系。 Hibernate将在这一方build立关系基础。 例如,假设我让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正在通过Post
的user
获得关系(而不是User
的posts
)。如果你有Post
的user
但是缺lessUser
的posts
,你会注意到这个区别。
你已经提到了mappedBy
和JoinColumn
不工作。 不过,我相信这其实是正确的做法。 请告诉我们,如果这种方法不适合你,给我们一些关于这个问题的更多信息。 我相信这个问题是由于别的。
编辑:
关于使用mappedBy
的一些额外的信息,因为它通常首先是困惑的。 在mappedBy
,我们把“属性名称”放在双向关系的反面,而不是表格的列名。
你在application.conf中使用正确的configuration吗?
db=mysql://user:pwd@host/database
我也面临一个类似的问题,通过给你在你的conf文件中使用的数据库用户名的pipe理员权限来解决。
由于您将直接保存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中添加外键。