为什么删除孤儿需要“级联全部”在 JPA/Hibernate 中运行?

发布于 2024-08-19 13:26:42 字数 1001 浏览 4 评论 0原文

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

但是这个配置不起作用。当我尝试使用级联“全部”时,它会运行。为什么删除孤立选项需要级联“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);
}

}

I try to map a one-to-many relation with cascade "remove" (jpa) and "delete-orphan", because I don't want children to be saved or persist when the parent is saved or persist (security reasons due to client to server (GWT, Gilead))

But this configuration doesn't work. When I try with cascade "all", it runs. Why the delete-orphan option needs a cascade "all" to run ?

Here is the code (without id or other fields for simplicity, the class Thread defines a simple many-to-one property without cascade):
when using the removeThread function in a transactional function, it does not run but if I edit cascade.Remove into cascade.All, it runs.

@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);
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

热风软妹 2024-08-26 13:26:42

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

JPA XML 也不支持它。

According to Java Persistence with Hibernate, cascade orphan delete is not available as a JPA annotation.

It is also not supported in JPA XML.

双手揣兜 2024-08-26 13:26:42

对于hibernate来说,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、hibernate 不尊重子元素的 CascadeType.DELETE 注释,可能出于相同的原因,CascadeType.REMOVE 也会忽略它们。

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

For hibernate, REMOVE and DELETE mean the same thing, check. 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;
                }
                        }

So for Hiberante there is no difference between REMOVE or DELETE, it's the same thing! Since JPA, hibernate, do not respect the CascadeType.DELETE annotation for child elements, could be same reason, they are also ignored for CascadeType.REMOVE.

Try with a CascasdeType.REFRESH if that helps (just a guess)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文