-->
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.  [ 1 post ] 
Author Message
 Post subject: [HHH-1196] Avoid unnecessary updates when cascading the dele
PostPosted: Thu Nov 24, 2005 1:36 pm 
Newbie

Joined: Thu Nov 24, 2005 12:59 pm
Posts: 2
I was directed here from jira: http://opensource2.atlassian.com/projec ... e/HHH-1196
so here go the gory details...

Hibernate version: Hibernate 3.1 rc3

Mapping documents:
Code:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="update" default-access="field">

    <class name="Category" table="category">
        <id name="id"><generator class="native"/></id>
        <version name="version"/>
        <property name="description" not-null="true" column="description"/>
        <many-to-one name="parent" column="parent_id" cascade="persist"/>
        <set name="children" inverse="true" cascade="all">
            <key column="parent_id"/>
            <one-to-many class="Category"/>
        </set>
    </class>

</hibernate-mapping>


The class:
Code:
public class Category implements Serializable
{
    private Long id;
    private int version;
    private String description;
    private Category parent;
    private Set<Category> children = new HashSet<Category>();

    public Category() {}

    public Category(Category parent) {
        this.parent = parent;
        parent.add(this);
    }

    public Long id() { return id; }
    public int version() { return version; }

    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }

    public Set<Category> children() { return Collections.unmodifiableSet(children); }

    public void detach() {
        if (parent != null)
            parent.remove(this);
    }

    protected void add(Category child) {
        children.add(child);
    }
    public void remove(Category child) {
        children.remove(child);
    }

    public String toString() { return description; }

    private static final long serialVersionUID = 1L;
}


Code between sessionFactory.openSession() and session.close():
Code:
Category root = new Category();
root.setDescription("Root Category");

Category c1 = new Category(root);
c1.setDescription("Child #1");

Category c2 = new Category(root);
c2.setDescription("Child #2");

session.save(root); session.flush(); session.clear();

root = (Category)session.load(Category.class, root.id());
Category c = root.children().iterator().next();
root.remove(c);
session.delete(c);
session.flush();


Hibernate issues these SQL statements:

- an update for the root entity incrementing the version
that's ok because the set of children has changed

- an unnecessary update for the child entity to be deleted
this update changes no fields (even version) and IMO is unnecessary

- the deletes for the chilren of deleted child (if any)

- the delete for deleted child

That unnecessary update is executed even when deleted child has no children.
Its children collection is changed from empty set to null
and that is detected as property change, hence the update.

A better strategy would be not to update entities that are going to be
deleted during the flush.

Name and version of the database you are using: HSQL

The generated SQL (show_sql=true):
Code:
Hibernate:
    insert
    into
        category
        (version, description, parent_id, id)
    values
        (?, ?, ?, null)
19:31:00,187 DEBUG IntegerType:79 - binding '0' to parameter: 1
19:31:00,203 DEBUG StringType:79 - binding 'Root Category' to parameter: 2
19:31:00,203 DEBUG LongType:71 - binding null to parameter: 3
Hibernate:
    call identity()
Hibernate:
    insert
    into
        category
        (version, description, parent_id, id)
    values
        (?, ?, ?, null)
19:31:00,203 DEBUG IntegerType:79 - binding '0' to parameter: 1
19:31:00,203 DEBUG StringType:79 - binding 'Child #2' to parameter: 2
19:31:00,218 DEBUG LongType:79 - binding '1' to parameter: 3
Hibernate:
    call identity()
Hibernate:
    insert
    into
        category
        (version, description, parent_id, id)
    values
        (?, ?, ?, null)
19:31:00,218 DEBUG IntegerType:79 - binding '0' to parameter: 1
19:31:00,218 DEBUG StringType:79 - binding 'Child #1' to parameter: 2
19:31:00,218 DEBUG LongType:79 - binding '1' to parameter: 3
Hibernate:
    call identity()
Hibernate:
    select
        category0_.id as id0_0_,
        category0_.version as version0_0_,
        category0_.description as descript3_0_0_,
        category0_.parent_id as parent4_0_0_
    from
        category category0_
    where
        category0_.id=?
19:31:00,281 DEBUG LongType:79 - binding '1' to parameter: 1
19:31:00,281 DEBUG IntegerType:123 - returning '0' as column: version0_0_
19:31:00,281 DEBUG StringType:123 - returning 'Root Category' as column: descript3_0_0_
19:31:00,281 DEBUG LongType:116 - returning null as column: parent4_0_0_
Hibernate:
    select
        children0_.parent_id as parent4_1_,
        children0_.id as id1_,
        children0_.id as id0_0_,
        children0_.version as version0_0_,
        children0_.description as descript3_0_0_,
        children0_.parent_id as parent4_0_0_
    from
        category children0_
    where
        children0_.parent_id=?
19:31:00,296 DEBUG LongType:79 - binding '1' to parameter: 1
19:31:00,296 DEBUG LongType:123 - returning '2' as column: id0_0_
19:31:00,296 DEBUG IntegerType:123 - returning '0' as column: version0_0_
19:31:00,296 DEBUG StringType:123 - returning 'Child #2' as column: descript3_0_0_
19:31:00,296 DEBUG LongType:123 - returning '1' as column: parent4_0_0_
19:31:00,296 DEBUG LongType:123 - returning '1' as column: parent4_1_
19:31:00,296 DEBUG LongType:123 - returning '2' as column: id1_
19:31:00,296 DEBUG LongType:123 - returning '3' as column: id0_0_
19:31:00,296 DEBUG IntegerType:123 - returning '0' as column: version0_0_
19:31:00,296 DEBUG StringType:123 - returning 'Child #1' as column: descript3_0_0_
19:31:00,296 DEBUG LongType:123 - returning '1' as column: parent4_0_0_
19:31:00,296 DEBUG LongType:123 - returning '1' as column: parent4_1_
19:31:00,296 DEBUG LongType:123 - returning '3' as column: id1_
Hibernate:
    select
        children0_.parent_id as parent4_1_,
        children0_.id as id1_,
        children0_.id as id0_0_,
        children0_.version as version0_0_,
        children0_.description as descript3_0_0_,
        children0_.parent_id as parent4_0_0_
    from
        category children0_
    where
        children0_.parent_id=?
19:31:00,312 DEBUG LongType:79 - binding '3' to parameter: 1
Hibernate:
    update
        category
    set
        version=?,
        description=?,
        parent_id=?
    where
        id=?
        and version=?
19:31:00,312 DEBUG IntegerType:79 - binding '1' to parameter: 1
19:31:00,312 DEBUG StringType:79 - binding 'Root Category' to parameter: 2
19:31:00,312 DEBUG LongType:71 - binding null to parameter: 3
19:31:00,312 DEBUG LongType:79 - binding '1' to parameter: 4
19:31:00,312 DEBUG IntegerType:79 - binding '0' to parameter: 5
Hibernate:
    update
        category
    set
        version=?,
        description=?,
        parent_id=?
    where
        id=?
        and version=?
19:31:00,328 DEBUG IntegerType:79 - binding '0' to parameter: 1
19:31:00,328 DEBUG StringType:79 - binding 'Child #1' to parameter: 2
19:31:00,328 DEBUG LongType:79 - binding '1' to parameter: 3
19:31:00,328 DEBUG LongType:79 - binding '3' to parameter: 4
19:31:00,328 DEBUG IntegerType:79 - binding '0' to parameter: 5
Hibernate:
    delete
    from
        category
    where
        id=?
        and version=?
19:31:00,328 DEBUG LongType:79 - binding '3' to parameter: 1
19:31:00,328 DEBUG IntegerType:79 - binding '0' to parameter: 2


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

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.