views:

1215

answers:

2

Hello,

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

}

thanks.

A: 

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

It is also not supported in JPA XML.

zor
Yes... but you can use provider specific extensions like the OP is doing here.
Pascal Thivent
Persistence with Hibernate needs to be updated. Orphan removal is possible with JPA 2.0 (http://java.dzone.com/articles/looking-forward-jpa-20?page=0,3)
Matt Brock
A: 

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)

Varun Mehta