Search code examples
springhibernatespring-mvcspring-boothibernate-session

Which is the better way of using Hibernate seesion.delete() - Delete by Id or delete by object?


I am working on an application that is built using Spring MVC, it is using Hibernate to interact with the data store. While I was trying to implement delete functionality, I figured out that there are multiple ways to implement session.delete(). Out of all, I am confused which one out of the following two is the better way(more specifically, standard way) to implement Hibernate seesion.delete().

As this API call would be turned into micro-service in the future stage, I guess it is the standard way to get userId from the web and not the entire object.

Method 1:

@Transactional    
public void deleteUser(User user) {
    sessionFactory.getCurrentSession().delete(user);
}

Method 2:

@Transactional
public void deleteUser(int userId) {
    Query q = session.createQuery("delete User where id = :userId");
    query.setParameter("userId", userId);
    q.executeUpdate();
}

Method 3:

@Transactional
public void deleteOrg(int userId) {
    User user = sessionFactory.getCurrentSession().get(User.class, userId);
    sessionFactory.getCurrentSession().delete(user);
}

Solution

  • Some more details to Gauillaume F.'s answer. I recommend going with method 4 (efficient, exposable as a service and idiomatic use of Hibernate).

    Method 1

    @Transactional    
    public void deleteUser(User user) {
        sessionFactory.getCurrentSession().delete(user);
    }
    
    • Deletion is synchronized with session cache
    • user must be an instance under Hibernate's control. So it cannot be directly exposed as a service.
    • Sufficiently efficient. It depends on how the instance is retrieved in the first place.

    Method 2

    @Transactional
    public void deleteUser(int userId) {
        Query q = session.createQuery("delete User where id = :userId");
        query.setParameter("userId", userId);
        q.executeUpdate();
    }
    
    • Efficient (no instance is loaded from database or put into session cache)
    • Can be directly exposed as a service
    • Not synchronized with session cache
    • Unnecessary use of HQL

    Method 3

    @Transactional
    public void deleteOrg(int userId) {
        User user = sessionFactory.getCurrentSession().get(User.class, userId);
        sessionFactory.getCurrentSession().delete(user);
    }
    
    • Sufficiently efficient (instance is first loaded from database, put into the session cache and then deleted)
    • Can be directly exposed as a service
    • Synchronized with session cache

    Method 4

    @Transactional
    public void deleteOrg(int userId) {
        User user = sessionFactory.getCurrentSession().load(User.class, userId);
        sessionFactory.getCurrentSession().delete(user);
    }
    
    • Efficient (no data is loaded; a proxy is put into the session cache instead)
    • Can be directly exposed as a service
    • Synchronized with session cache