Java JPA OneToMany和MANYTONE throw:实体列映射中的重复列(应使用insert=";false";update=";false";映射)
我有三个类,其中一个名称是User,这个用户有其他类实例。像这样,Java JPA OneToMany和MANYTONE throw:实体列映射中的重复列(应使用insert=";false";update=";false";映射),java,hibernate,jpa,one-to-many,many-to-one,Java,Hibernate,Jpa,One To Many,Many To One,我有三个类,其中一个名称是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> bP
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;
}
及
到
及
一切正常 我不太清楚您的问题(“空表”的含义等,或者
mappedBy
和JoinColumn
如何不起作用)
我想你是在尝试建立一种双向关系
首先,你需要决定哪一方“拥有”关系。Hibernate将在此基础上建立关系。例如,假设我让Post
一方拥有关系(我简化了您的示例,只是为了保持重点),映射将如下所示:
(希望语法正确。我只是凭记忆写的。不过想法应该是好的)
公共类用户{
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy=“user”)
私人名单员额;
}
公营职位{
@manytone(fetch=FetchType.LAZY)
@JoinColumn(name=“user\u id”)
私人用户;
}
通过这样做,Post
的表将有一列user\u id
,用于存储关系。Hibernate正在通过Post
中的user
获取关系(而不是user
中的posts
。如果您有Post
的user
但缺少用户的posts
,您会注意到区别
您提到了mappedBy
和JoinColumn
不起作用。不过,我相信这其实是正确的做法。请告知这种方法是否对您不起作用,并向我们提供有关该问题的更多信息。我相信这个问题是由其他原因造成的
编辑:
关于mappedBy
的使用只需要多一点额外的信息,因为一开始它通常会让人困惑。在mappedBy
中,我们将“属性名”放在双向关系的另一侧,而不是表列名。您不应该使用单向@OneToMany
注释,因为:
它生成低效的SQL语句
它会创建一个额外的表,增加数据库索引的内存占用
现在,在第一个例子中,双方都拥有协会,这很糟糕
虽然@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;
}
公共类用户{
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy=“user”)
公开名单使徒;
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy=“user”)
公开名单;
}
公共类BPost扩展了Post{
@manytone(fetch=FetchType.LAZY)
公共用户;
}
公共类APAST扩展Post{
@manytone(fetch=FetchType.LAZY)
公共用户;
}
你到底是怎么失败的?确切地说,你在寻求什么帮助?如果第一个解决方案对您有效,为什么不继续使用它呢?因为jpa创建了User_apst和User_BPost表,但没有向这些表添加任何行。我觉得我错了。我在《阿德里安邮报》上增加了额外的信息。当我根据您的建议更改注释时,它包含错误。对不起,兄弟,我一开始无法理解您的答案。:)嗨,阿德里安,我不知道这是怎么回答他的问题的。然而,我也有同样的问题。i、 在您的解决方案中,用户只有“Post”列表,但在他的例子中,他有类“apst”和“bPost”,这两个Post类都指向用户。所以,能否请您修改您的答案,向不同的类显示引用用户和具有多个r/s的用户?谢谢。@WowBow这只是因为他的问题仅仅与双向映射的方式有关,而与多个一对多关系无关。不会更新答案,因为我想让答案远离与问题无关的不必要的干扰。如果您有其他问题,请随意将其作为另一个问题提出。@WowBow如果您的问题是关于如何拥有2个子类,并且您希望在User
中使用方法来获得相应的aPosts
和bPosts
,则有很多方法。我个人的偏好是让它变得简单:让User
与Post
有一对多的关系,并通过运行时过滤内部集合
为getAPosts()
和getBPosts()
提供getter。您也可以像OP一样进行操作,同时将APST和BPost视为完全不同的实体,并维护其自己的用户关系(没有什么比使用描述的方式定义2个OneToMany关系更重要的了)。我一直在尝试这一点。然而,由于明显的循环引用,我不断得到堆栈溢出(用户有一个apst列表,它有用户,它有一个apst列表,…堆栈溢出错误)。有关于这个的指针吗?获得StackOverflow的唯一方法是从子级调用父级的方法,然后在子级调用相同的方法。但是,这不是因为我建议的映射。谢谢Vlad。我刚刚发现,这似乎表明是将对象序列化为JSON导致了问题。
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id")
public List<APost> aPosts;
@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")
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;
}
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;
}