首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OneToMany RelationShip中的删除实体

OneToMany RelationShip中的删除实体
EN

Stack Overflow用户
提问于 2011-04-13 05:46:39
回答 5查看 24.1K关注 0票数 6

如何删除OneToMany关系中的实体。

代码语言:javascript
复制
@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);
       }
    }
}

专业实体内部

代码语言:javascript
复制
@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中有这样的代码:

代码语言:javascript
复制
@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不能工作。不知道为什么?请帮帮忙。我需要驱逐缓存吗?

EN

回答 5

Stack Overflow用户

发布于 2011-04-13 07:01:48

如果职业只是这种关系的一部分,那么您可以保证,当从用户集合中删除某个职业时,通过在该关系的OneToMany端启用orphanRemoval,该职业也会从数据库中删除。

代码语言:javascript
复制
@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.

票数 10
EN

Stack Overflow用户

发布于 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“

票数 5
EN

Stack Overflow用户

发布于 2011-04-13 05:57:51

您可以尝试清除profession中的user字段:

代码语言:javascript
复制
public void removeProfession(Profession profession){
       if(this.professions != null){
          professions.remove(profession);
          profession.setUser(null);  // disassociate profession from user
       }
    }

为了安全起见,我还会检查传入的职业的当前用户是否等于this,以防有人传入属于另一个用户的职业。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5642002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档