如何删除OneToMany关系中的实体。
@Entity
@NamedQueries({
@NamedQuery(name="User.findByUserNamePassword",
query="select c from User c where c.userName = :userName AND c.password = :password")
})
@Table(name="\"USER\"")
public class User implements Serializable {
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemove=true)
private List<Profession> professions;
public List<Profession> getProfessions() {
return professions;
}
public void setProfessions(List<Profession> professions) {
this.professions = professions;
}
public void addProfession(Profession profession){
if(this.professions == null){
this.professions = new ArrayList<Profession>();
}
this.professions.add(profession);
profession.setUser(this);
}
public void removeProfession(Profession profession){
if(this.professions != null){
professions.remove(profession);
profession.setUser(null);
}
}
}专业实体内部
@Entity
public class Profession implements Serializable {
@ManyToOne
@JoinColumn(name="UserId", nullable=false)
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}然后在我的EJB中有这样的代码:
@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ScholarEJB{
/**
* Add a profession to a target user
* @param user
* @param profession
*/
public void addProfession(User user, Profession profession){
//Put the user in a managed state. It is important to do this before
//adding a new profession onto user
user = find(User.class, user.getId());
user.addProfession(profession);
this.create(user); //This is persist action
}
public void removeProfession(User user, Profession profession){
//Put the user in a managed state. It is important to do this before
//adding a new profession onto user
user = find(User.class, user.getId());
user.remove(user);
this.update(user); //merge action
//this.create(user) //also try this as well, but it does not work
}
}现在addProfession可以很好地工作,但是removeProfession不能工作。不知道为什么?请帮帮忙。我需要驱逐缓存吗?
发布于 2011-04-13 07:01:48
如果职业只是这种关系的一部分,那么您可以保证,当从用户集合中删除某个职业时,通过在该关系的OneToMany端启用orphanRemoval,该职业也会从数据库中删除。
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemoval=true)
private List<Profession> professions;这就是JPA2.0规范所声明的
JPA2.0规范规定
指定为OneToOne或OneToMany的
关联支持使用orphanRemoval选项。当orphanRemoval生效时,以下行为适用:
如果从关系中删除作为关系目标的实体(通过将关系设置为null或从关系集合中删除该实体),则删除操作将应用于孤立的实体。移除操作在刷新操作时应用。orphanRemoval功能旨在用于由其父实体私有的实体。可移植的应用程序不能依赖于特定的移除顺序,也不能将孤立的实体重新分配给另一个关系,也不能试图将其持久化。如果被孤立的实体是分离的、新的或已删除的实体,则orphanRemoval的语义不适用。
如果移除操作应用于受管理的源实体,则移除操作将根据第3.2.3节的规则级联到关系目标(因此不需要为关系指定cascade=REMOVE )20.
发布于 2011-04-13 21:35:03
我的猜测是,您的用户与profession具有OneToMany关系,而您的User对象具有Profession。当您删除该职业时,该用户仍具有该引用。因为映射是级联持久化的,所以它是专业的持久化。
在删除该职业之前,您需要确保将该职业从用户的职业中删除。
如果您使用的是EclipseLink,有一个属性也可能会有所帮助,但修复代码以正确维护模型是最好的解决方案。您还可以删除级联持久化。
"eclipselink.persistence-context.persist-on-commit"="false“
或者,"eclipselink.persistence-context.commit-without-persist-rules"="true“
发布于 2011-04-13 05:57:51
您可以尝试清除profession中的user字段:
public void removeProfession(Profession profession){
if(this.professions != null){
professions.remove(profession);
profession.setUser(null); // disassociate profession from user
}
}为了安全起见,我还会检查传入的职业的当前用户是否等于this,以防有人传入属于另一个用户的职业。
https://stackoverflow.com/questions/5642002
复制相似问题