JPA OneToMany 和 ManyToOne throw:实体列映射中的重复列(应使用 insert=“false” update=“false”进行映射)

2022-08-31 19:50:08

我有三个类,其中一个名称是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;
 }

它的工作方式是这样的,但在数据库中生成空表。其中必须包含外键。当我尝试使用和注释时,我失败了。如何解决此问题?mappedByJoinColumn

额外信息:

当我改变与;

 @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")

一切都很好。:)


答案 1

我不太确定你的问题(“空表”等的含义,或者如何和不起作用)。mappedByJoinColumn

我认为你试图做一个双向的关系。

首先,你需要决定哪一方“拥有”这段关系。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;
}

这样,的表将具有一个存储关系的列。休眠是通过 in(而不是 in )获取关系。如果您拥有 's 但缺少 's,您会注意到差异。Postuser_iduserPostpostsUserPostuserUserposts

你已经提到并且不起作用。但是,我认为这实际上是正确的方法。请告知此方法是否对您不起作用,并向我们提供有关该问题的更多信息。我认为问题出在别的地方。mappedByJoinColumn


编辑:

只是一些关于使用的额外信息,因为它通常一开始令人困惑。在 中,我们将“属性名称”放在双向关系的另一侧,而不是表列名。mappedBymappedBy


答案 2

切勿使用单向批注,因为:@OneToMany

  1. 它生成低效的 SQL 语句
  2. 它会创建一个额外的表,从而增加数据库索引的内存占用量

现在,在你的第一个例子中,双方都拥有这个协会,这很糟糕。

虽然会让一方负责协会,但这绝对不是最好的选择。因此,请始终使用侧面的属性。@JoinColumn@OneToManymappedBy@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;
}

推荐