为啥 delete-orphan 需要“全部级联”才能在 JPA/Hibernate 中运行?

Posted

技术标签:

【中文标题】为啥 delete-orphan 需要“全部级联”才能在 JPA/Hibernate 中运行?【英文标题】:Why delete-orphan needs "cascade all" to run in JPA/Hibernate?为什么 delete-orphan 需要“全部级联”才能在 JPA/Hibernate 中运行? 【发布时间】:2010-01-29 09:02:15 【问题描述】:

我尝试使用级联“remove”(jpa)和“delete-orphan”映射一对多关系,因为我不希望在保存或保留父级时保存或保留子级(安全由于客户端到服务器(GWT,Gilead)的原因)

但是这个配置不起作用。当我尝试使用级联“全部”时,它会运行。为什么 delete-orphan 选项需要级联“all”才能运行?

这里是代码(为简单起见,没有id或其他字段,类Thread定义了一个简单的多对一属性,没有级联): 在事务函数中使用removeThread 函数时,它不会运行,但如果我将cascade.Remove 编辑为cascade.All,它会运行。

@Entity
public class Forum 
   
private List<ForumThread>   threads;


/**
 * @return the topics
 */
@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
public List<ForumThread> getThreads()

    return threads;


/**
 * @param topics the topics to set
 */
public void setThreads(List<ForumThread> threads)

    this.threads = threads;


public void addThread(ForumThread thread)

    getThreads().add(thread);
    thread.setParent(this);


public void removeThread(ForumThread thread)

    getThreads().remove(thread);



【问题讨论】:

【参考方案1】:

根据 Java Persistence with Hibernate,级联孤儿删除不能用作 JPA 注释。

JPA XML 也不支持它。

【讨论】:

是的...但是您可以使用提供程序特定的扩展,就像 OP 在这里所做的那样。 Hibernate 的持久性需要更新。使用 JPA 2.0 (java.dzone.com/articles/looking-forward-jpa-20?page=0,3) 可以删除孤立项【参考方案2】:

对于休眠模式,REMOVE 和 DELETE 的含义相同,请检查。 AnnotationBinder#getCascadeStrategy()

      while ( cascadeType.hasNext() ) 
        switch ( cascadeType.next() ) 
            case ALL:
                cascade.append( "," ).append( "all" );
                break;
            case SAVE_UPDATE:
                cascade.append( "," ).append( "save-update" );
                break;
            case PERSIST:
                cascade.append( "," ).append( "persist" );
                break;
            case MERGE:
                cascade.append( "," ).append( "merge" );
                break;
            case LOCK:
                cascade.append( "," ).append( "lock" );
                break;
            case REFRESH:
                cascade.append( "," ).append( "refresh" );
                break;
            case REPLICATE:
                cascade.append( "," ).append( "replicate" );
                break;
            case EVICT:
                cascade.append( "," ).append( "evict" );
                break;
            case DELETE:
                cascade.append( "," ).append( "delete" );
                break;
            case DELETE_ORPHAN:
                cascade.append( "," ).append( "delete-orphan" );
                break;
            case REMOVE:
                cascade.append( "," ).append( "delete" );
                break;
                
                        

因此,对于 Hiberante,REMOVE 或 DELETE 没有区别,它们是一回事!由于 JPA,休眠,不尊重子元素的 CascadeType.DELETE 注释,可能是相同的原因,它们也被 CascadeType.REMOVE 忽略。

如果有帮助,请尝试使用 CascasdeType.REFRESH(只是猜测)

【讨论】:

以上是关于为啥 delete-orphan 需要“全部级联”才能在 JPA/Hibernate 中运行?的主要内容,如果未能解决你的问题,请参考以下文章

一对多,多对一,注意事项总结

D365 9.0 中IncidentResolution不产生PrincipalObjectAccess记录

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥需要 preferredMaxLayoutWidth?