1

I want to implement deleteAll method that will be delete all User entities with their associations, at the same time I want to prevent java.lang.OutOfMemoryError exception when fetching users collection in memory heap.

My current implementation looks like the code snippet below:

public void deleteAll() {
    final int PAGE_SIZE = 15;
    final int PAGE_NUMBER = 0;
    final String SORTING_PROPERTY_NAME = "id";
    List<User> result;

    Session session = sessionFactory.getCurrentSession();
    Criteria criteria = session.createCriteria(User.class);
    criteria.addOrder(Order.asc(SORTING_PROPERTY_NAME));
    criteria.setFirstResult(PAGE_NUMBER);
    criteria.setMaxResults(PAGE_SIZE);

    do {
        result = criteria.list();
        result.forEach(session::delete);
    } while (result.size() == PAGE_SIZE);
}

As you see I am using pagination approach so I fetched one bulk of data then delete it and so on. How this is achieved in reality with Hibernate? Thank you for help.

Vladimir Vagaytsev
  • 2,871
  • 9
  • 33
  • 36
Dimon
  • 763
  • 3
  • 7
  • 22
  • 2
    Take a look at: http://stackoverflow.com/questions/3492453/hibernate-and-delete-all. Could be helpful. Current approach looks quite inefficient, you have to read the entire table then delete each record, too many DB queries. – Vladimir Vagaytsev Jul 31 '16 at 18:03

2 Answers2

2

Try this:

sessionFactory.getCurrentSession().createQuery("delete from User").executeUpdate();

You don't need to fetch all records (or any part) to delete them. Also look here. Maybe it will be useful.

Unfortunately, this approach will not trigger cascade removal. Maybe you can approve another approach. For example, create additional column "is_deleted" and set value true if it is removed. After this you can schedule a job at night. This job will actualy remove some part of these users by your approach. But you will have to add a condition to your get\fetch methods to take into account only is_deleted=false users.

  • I realized that my approach (described in question) is a low performance because to many calls to db. So I will use hsl for table truncate. But with this approach in case association like many-to-many I am forced to use native sql query for truncating association table. Thanks Aliaksandr Budnikau and Vladimir Vagaytsev for help! – Dimon Aug 18 '16 at 11:26
1

You can actually use hql or jpl to do this, assuming there are no cascades.

public int hqlTruncate(String user){ String hql = String.format("delete from %s",user); Query query = session.createQuery(hql) return query.executeUpdate(); }

muru
  • 61
  • 7