在使用hibernate和jpa的spring mvc项目中,我有一个person
实体和一个role
实体。每个person
可以有多个roles
,但每个role
只能有一个person
。如何为现有role
保存新的person
?
我已经阅读了很多这方面的帖子。如果我尝试保存新的role
,我会收到一条错误,指出无法保存分离的实体。但是,如果我尝试保存现有的person
,则该角色不会被保存。我阅读this posting建议将hibernate注释移动到getter,但是当我这样做时,我得到一个引用未知属性的hibernate映射错误。并且this posting表示新错误的解决方法是将注释移回到getter,而不提及分离实体错误中的结果。因此,各种堆栈溢出问题似乎都指向一个圆圈。 那么如何修复我的代码以实际保存新的子实体?
这是人:
@Entity(name = "RimPerson")
@Table(name = "rim_person")
public class RimPerson {
@Id
@Column(name="hppid")
@GenericGenerator(name = "generator", strategy = "native")
@GeneratedValue(generator = "generator")
private Long hppid;
@OneToMany(targetEntity = RimRole.class, cascade = {CascadeType.ALL
}, fetch = FetchType.EAGER)
@JoinColumn(name = "player_rimperson_HJID")
private List<RimRole> playedRoles;
//other properties and getters and setters
}
角色是:
@Entity(name = "RimRole")
@Table(name = "rim_role")
public class RimRole {
@Id
@Column(name="hppid")
@GenericGenerator(name = "generator", strategy = "native")
@GeneratedValue(generator = "generator")
private Long hppid;
@ManyToOne(targetEntity = RimPerson.class, cascade = {CascadeType.ALL
}, fetch = FetchType.LAZY)
@JoinColumn(name = "player_rimperson_HJID", nullable=true)
private RimPerson player;
//other stuff and getters and setters
}
以下是存储库层中的JPQL:
@Override
public void saveRIMPerson(RimPerson myperson) throws DataAccessException{
if (myperson.getHppid() == null) {this.em.persist(myperson);}
else {this.em.merge(myperson);}
}
可以找到相关课程的完整代码at this link。
答案 0 :(得分:1)
实体RimPerson
和RimRole
之间存在双向一对多关系。因此,您需要使用mappedBy
属性告知hibernate哪个是关联所有者,如果one-to-many
关系many
方被视为关联所有者,那么在{{1}映射应该是这样的:
RimPerson
请注意,我们必须从此处删除 @OneToMany(targetEntity = RimRole.class, mappedBy="player", cascade = {CascadeType.ALL
}, fetch = FetchType.EAGER)
private List<RimRole> playedRoles;
注释。此外,mappedBy属性的值应与您在@JoinColumn
中定义的属性名称RimRole
匹配。
现在,对于双向关联,您需要从实体的两侧设置属性,这意味着:
player
尝试使用这些更改来更新代码并运行应用程序,这应该可以解决问题。