-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: How to delete entity by removing from collection
PostPosted: Wed Jun 05, 2013 11:58 am 
Beginner
Beginner

Joined: Sun Jan 11, 2009 2:47 pm
Posts: 21
I have a bidirectional many-to-one list mapping, the collection and links are maintained by the "one" side. Mapping is:

Code:
    <class name="xxx.Question" table="questions">
        ...
        <list name="choices" cascade="all">
            <key column="question_id" not-null="true"/>
            <list-index column="position"/>
            <one-to-many class="xxx.Choice"/>
        </list>
        ...
    </class>
   
    <class name="xxx.Choice" table="choices">
        ...
        <many-to-one name="question" column="question_id" class="xxx.Question" update="false" insert="false" not-null="true"/>
        ...
    </class>


To add a Choice, I first obtain a Question, then I add the Choice to the Question's collection and set the Choice's Question reference. Then I persist() and Hibernate works as expecting, adding the Choice to the database.

When I remove a Question from the database, Hibernate also, as desired and expected, removes all the associated Choices.

However, I'm having some trouble removing a single Choice. I remove Choices by their ID since it's for a web application and it's all the info I have. Right now my code is this:

Code:
public class Question {
    ....

    private List<Choice> choices;

    public void removeChoice (User current, long choice_id) throws IllegalArgumentException, SecurityException {
        User.requireAll(current, Role.CAN_EDIT_QUESTIONS);
        for (Choice c: choices)
            if (c.getId() == choice_id) {
                c.setQuestion(current, null);
                choices.remove(c);
                // i don't know how to do this without explicitly telling hibernate to remove
                try {
                    HibernateUtil.getCurrentSession().delete(c);
                } catch (Throwable t) {
                    throw new IllegalArgumentException(t);
                }
                return;
            }
        throw new IllegalArgumentException("Unknown choice ID.");
    }

    ....
}


Basically, I look through the Question's Choice list, remove it from the list, set the Question reference in the Choice to null, then tell Hibernate to delete the choice.

It's important that I keep the entity instance synchronized with the database after a remove, and it's also important that I don't remove a choice from the database if it's not part of this specific Question, otherwise I would just tell Hibernate to remove the Choice with the specified question_id and choice_id and be done with it.

I'm unsatisfied with the transparency of Hibernate in my above code -- I have to take a separate step to remove it from the database in addition to updating the entity instance.

If I don't explicitly delete() the Choice, Hibernate ends up just updating the list index column but not removing the Choice, leaving Choices in the database with duplicate list index values for the same question.

Can I make Hibernate automatically delete the Choice simply by removing it from the Question's choice container (or alternatively by setting the Choice's Question reference to null)?

Thanks!


Top
 Profile  
 
 Post subject: Re: How to delete entity by removing from collection
PostPosted: Thu Jun 06, 2013 6:31 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Yes this is possible in Hibernate. This feature is a special cascade option not included in Cascade.all,
it's called delete-orphan:

org.hibernate.annotations.CascadeType.DELETE_ORPHAN

This extra and special setting enables deletion of associated objects when they’re removed from the association, that is, from a collection. If you enable this setting on an entity collection, you’re telling Hibernate that the associated objects don’t have shared references and can be safely deleted when a reference is removed from the collection.


Top
 Profile  
 
 Post subject: Re: How to delete entity by removing from collection
PostPosted: Tue Jul 02, 2013 11:37 pm 
Beginner
Beginner

Joined: Sun Jan 11, 2009 2:47 pm
Posts: 21
That was my problem. Thank you!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.