【问题标题】:JPA OneToMany and ManyToOne throw: Repeated column in mapping for entity column (should be mapped with insert="false" update="false")JPA OneToMany 和 ManyToOne 抛出:实体列映射中的重复列(应使用 insert="false" update="false" 进行映射)
【发布时间】:2012-11-28 12:13:32
【问题描述】:

我有三个类,其中一个是用户,这个用户有其他类实例。像这样;

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

一切正常。 :)

【问题讨论】:

  • 你到底是怎么失败的?确切地说,您在寻求什么帮助?如果第一个解决方案对您有用,为什么不坚持下去呢?
  • 因为 jpa 创建了 User_APost 和 User_BPost 表,但它没有向该表添加任何行。感觉我错了。

标签: java hibernate jpa one-to-many many-to-one


【解决方案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;
}

通过这样做,Post 的表将有一个列user_id 存储关系。 Hibernate 通过Post 中的user 获取关系(而不是User 中的posts。如果您有Postuser 但缺少User 的@987654334,您会注意到差异@)。

您提到mappedByJoinColumn 不起作用。但是,我相信这实际上是正确的方法。请告诉我们这种方法是否不适合您,并就该问题向我们提供更多信息。我认为问题是由其他原因引起的。


编辑:

关于使用mappedBy 的一些额外信息,因为起初它通常令人困惑。在mappedBy中,我们把“属性名”放在双向关系的对面,而不是表列名。

【讨论】:

  • 我添加了额外的信息来发布阿德里安。当我根据您的建议更改注释时,它包含错误。
  • 对不起兄弟,我一开始没听懂你的回答。 :)
  • 嗨@Adrian,我不确定这如何回答他的问题。但是,我有同样的问题。即在您的解决方案中,用户只有“帖子”列表,但在他的情况下,他有“APost”和“bPost”类,并且这两个帖子类都引用了用户。那么可以通过向引用 User 和 User 的不同类来修改您的答案来修改这些类的 ManyToOne r/s 吗?谢谢。
  • @WowBow 很简单,因为他的问题仅与做双向映射的方式有关,与多个一对多关系无关。不会更新答案,因为我想让答案远离与问题无关的不必要的干扰。如果您有其他问题,请随时将其作为另一个问题提出。
  • @WowBow 如果您的问题是关于如何拥有 2 个子类,并且您希望在 User 中有方法来获得对应的 aPostsbPosts,有很多方法。我个人的偏好是让它变得简单:让UserPost 具有一对多的关系,并通过运行时过滤内部Collection&lt;Post&gt;getAPosts()getBPosts() 提供getter。您也可以像 OP 一样进行操作,同时将 APost 和 BPost 视为完全不同的实体并保持其自己的 user 关系(无非是使用描述的方式定义 2 个 OneToMany 关系)。
【解决方案2】:

你不应该使用单向的@OneToMany注解,因为:

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

现在,在您的第一个示例中,双方都拥有该关联,这很糟糕。

虽然@JoinColumn 会让@OneToMany 一方负责协会,但这绝对不是最佳选择。因此,请始终在@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;
}

【讨论】:

  • 我一直在尝试这个。但是,由于明显的循环引用,我不断收到堆栈溢出(用户有 APost 列表,其中有用户,有 APost 列表,......堆栈溢出错误)。对此有任何指示吗?
  • 获取 StackOverflow 的唯一方法是从子级调用父级的方法,该方法又在子级中调用相同的方法。但是,这不是由于我建议您的映射。
  • 谢谢弗拉德。我刚刚找到stackoverflow.com/questions/17445657/…,这似乎表明导致问题的原因是对象序列化为 JSON。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多