James
James

Reputation: 1780

Cascading hibernate delete when setting a collection to 'new ArrayList()'

I have an object mapped with hibernate that contains an id and a collection. At some point in time when the object contains items in it's collection I want to do obj.setCollection(new ArrayList()) and have it delete the items from the database that were previously in the collection. If anyone could assist it would be much appreciated. Code to illustrate problem:

ORM: Foo 1-* Bar and Bar 1-1 Foo

class Foo {
    Long id;
    List<Bar> bars;

    //getters & setters
}

<hibernate-mapping>
    <class name="domain.Foo" table="Foos">
        <id name="id" type="long" column="id">
            <generator class="native" />
        </id>
        <list name="bars" lazy="true" cascade="all">
            <key column="FOO_ID" not-null="true" />
            <index column="SEQUENCE" />
            <one-to-many class="domain.Bar" />
        </list>     
    </class>    
</hibernate-mapping>

@Entity
@Table(name="Bars")
public class Bar {
    private Long id;
    private Foo foo;
    private String name;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="ID")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @ManyToOne
    @JoinColumn(name="FOO_ID", insertable=false, updatable=false)
    public Foo getFoo() {
        return foo;
    }

    public void setFoo(Foo foo) {
        this.foo = foo;
    }

    @Column(name="NAME")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Upvotes: 2

Views: 4198

Answers (4)

axtavt
axtavt

Reputation: 242686

If you want Hibernate to remove objects from the database when you remove them from the collection, you need to configure delete-orphan option for that collection:

<list name="bars" lazy="true" cascade="all-delete-orphan">

Though in this case you cannot replace the collection, you need to use collection methods instead (see Ralph's answer and remove collection with delete-orphan not work with null assignment? :()

Upvotes: 1

Ralph
Ralph

Reputation: 120781

You should never replace a collection manged by Hibernate (for example if you have an object containing a collection, and this object is loaded by Hibernate) by an new collection!

Always use the collection methods (add, remove, clear, ...) to manipulate the method.

Upvotes: 3

Maurice Perry
Maurice Perry

Reputation: 32831

Or something like this (I like to encapsulate fields):

class Foo {
    Long id;
    List<Bar> bars = new ArrayList<Bar>();

    ...

    public List<Bar> getBars() {
        return new ArrayList<Bar>(bars);
    }

    public void setBars(List<Bar> newBars) {
        bars.clear();
        bars.addAll(newBars);
    }

    public void addBar(Bar bar) {
        bars.add(bar);
    }

    public void removeBar(Bar bar) {
        bars.remove(bar);
    }
}

Upvotes: 0

Guillaume
Guillaume

Reputation: 18865

What you probably want to do is :

obj.getCollection().clear();

Upvotes: 3

Related Questions