javahibernate

Hibernate Delete query


When I try to delete an entry from a db, using

session.delete(object) 

then I can the following:

1) If the row is present in DB then two SQL queries are getting executed: A select and then a delete

2) If the row is not present in the DB then only the select query is getting executed

But again this is not the case for update. Irrespective of the presence of DB row, only the update query is getting executed.

Please let me know why this kind of behaviour for delete operation. Isn't it a performance issue since two queries are getting hit rather than one?

Edit:

I am using hibernate 3.2.5

Sample code:

SessionFactory sessionFactory = new Configuration().configure("student.cfg.xml").buildSessionFactory();
    Session session = sessionFactory.openSession();
    Student student = new Student();
    student.setFirstName("AAA");
    student.setLastName("BBB");
    student.setCity("CCC");
    student.setState("DDD");
    student.setCountry("EEE");
    student.setId("FFF");
    session.delete(student);
    session.flush();
            session.close();

cfg.xml

<property name="hibernate.connection.username">system</property>
    <property name="hibernate.connection.password">XXX</property>
    <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
    <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521/orcl</property>      
    <property name="hibernate.jdbc.batch_size">30</property>
    <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
    <property name="hibernate.cache.use_query_cache">false</property>
    <property name="hibernate.cache.use_second_level_cache">false</property>
    <property name="hibernate.connection.release_mode">after_transaction</property>
    <property name="hibernate.connection.autocommit">true</property>
    <property name="hibernate.connection.pool_size">0</property>
    <property name="hibernate.current_session_context_class">thread</property>    
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">update</property>        

hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.infy.model.Student" table="STUDENT">
    <id name="id" column="ID">
        <generator class="assigned"></generator>
    </id>
    <property name="firstName" type="string" column="FIRSTNAME"></property>
    <property name="lastName" type="string" column="LASTNAME"></property>
    <property name="city" type="string" column="CITY"></property>
    <property name="state" type="string" column="STATE"></property>
    <property name="country" type="string" column="COUNTRY"></property>        
</class>


Solution

  • The reason is that for deleting an object, Hibernate requires that the object is in persistent state. Thus, Hibernate first fetches the object (SELECT) and then removes it (DELETE).

    Why Hibernate needs to fetch the object first? The reason is that Hibernate interceptors might be enabled (https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/events.html), and the object must be passed through these interceptors to complete its lifecycle. If rows are deleted directly in the database, the interceptor won't run.

    On the other hand, it's possible to delete entities in one single SQL DELETE statement using bulk operations:

    Query q = session.createQuery("delete Entity where id = X");
    q.executeUpdate();