为啥 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记录