JPA2.0:删除OneToMany关系中的实体

JPA2.0:删除OneToMany关系中的实体,jpa,ejb,jpa-2.0,one-to-many,Jpa,Ejb,Jpa 2.0,One To Many,如何删除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 Serializ

如何删除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);
       }
    }
}
然后在我的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
不起作用。不知道为什么?请帮忙。是否需要清除缓存?

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

public void removeProfession(Profession profession){
       if(this.professions != null){
          professions.remove(profession);
          profession.setUser(null);  // disassociate profession from user
       }
    }

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

如果职业只是此关系的一部分,然后,您可以通过在关系的OneToMany端启用“删除”来保证当从用户集中删除某个职业时,该职业也将从数据库中删除

@OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemoval=true)
private List<Profession> professions;
@OneToMany(mappedBy=“user”,cascade=CascadeType.ALL,orphan=true)
私人职业名单;
这就是JPA2.0规范所述

JPA2.0规范规定:

指定为 ONETONE或OneToMany支持使用 孤儿移除选项。这个 以下行为适用于以下情况: 孤儿院搬迁生效:

如果一个实体是 关系将从中删除 关系(通过设置 与null的关系或删除 关系中的实体 集合),删除操作将 将应用于正在创建的实体 孤儿。删除操作是无效的 冲洗时应用 活动孤儿院 功能是为实体设计的 是他们私人“拥有”的 父实体。便携式应用程序 否则不得依赖于 具体的移除顺序,并且必须 不重新分配已删除的实体 孤立于另一种关系或 否则,请尝试将其持久化。如果 孤立的实体是一个 分离、新建或删除的实体 孤儿移除的语义不存在 申请

如果删除操作应用于 一个托管源实体,删除 操作将级联到 关系目标符合 第3.2.3节的规则(以及 没有必要具体说明 cascade=为该对象删除 关系[20]


这是我原来问题的答案,但我不知道这是否是最好的

我的EJB bean

@PersistenceContext(unitName="Bridgeye2-ejbPU")
private EntityManager em;

public <T> T create(T t) {
    em.persist(t);
    return t;
}

public <T> T find(Class<T> type, Object id) {
    return em.find(type, id);
}

public <T> void delete(T t) {
    t = em.merge(t);
    em.remove(t);
}

public <T> void removeAndClearCaches(T t){
    this.delete(t);
    clearCaches();
}

public <T> T update(T t) {
    return em.merge(t);    

我的猜测是,你的用户和专业有一个单一的关系,而你的用户对象有这个专业。当您删除该职业时,用户仍然拥有该参考。因为映射是级联持久化的,所以它重新持久化了这个职业

您需要确保在删除该职业之前将其从用户的职业中删除

如果您使用的是EclipseLink,那么有一个属性可能也会有所帮助,但修复代码以正确维护模型是最好的解决方案。您还可以删除级联

“eclipselink.persistence context.persistent on commit”=“false”

或者,
“eclipselink.persistence context.commit without persistent rules”=“true”

我刚刚在OneToMany关系中添加了
orphanRemoving=true
,并解决了它

请求编号

@OneToMany(mappedBy = "solicitud", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
@NotAudited
private List<RetornoMenor> hijosRetorno;

试一下,也不行。我在删除后打印出职业列表,在我坚持/合并之前,列表恢复正确。但是当我持久化/合并时,这不会反映在我的数据库中。我尝试了它,但仍然不起作用。但我知道什么是有效的。我必须清除二级缓存才能正常工作<代码>专业=em.merge(专业);em.remove(专业);em.getEntityManagerFactory().getCache().ReceictAll(),这很有效,但我不确定这是否是最好的方法。你可以发布更新方法的功能吗?它表示它执行合并,这在当前代码中不清楚或不明显。在oneToMany关系中,正确的注释是orphanRemove=true,而不是orphanRemove=true
/**
 * Add a new profession 
 */
public void addNewProfession(){
    Profession profession = new Profession();        
    newProfessions.add(profession);        
}

/**
 * Remove the profession
 * @param profession
 */
public void removeProfession(Profession profession){
    //This will remove the `profession` of the list
    //at the presentation layer
    this.myProfessions.remove(profession);  
    //This will remove the `profession` of the list
    //at the persistence layer
    scholarEJB.removeAndClearCaches(profession);
}
@OneToMany(mappedBy = "solicitud", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
@NotAudited
private List<RetornoMenor> hijosRetorno;
@OneToMany(mappedBy = "solicitud", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
@NotAudited
private List<RetornoMenor> hijosRetorno;