2016-07-31 12 views
0

Ich möchte deleteAll Methode implementieren, die alle User Entities mit ihren Zuordnungen gelöscht werden, gleichzeitig möchte ich verhindern, java.lang.OutOfMemoryError Ausnahme beim Abrufen von Benutzer Sammlung im Speicher Heap.Hibernate: alle Entitäten mit Zuordnungen auf einmal löschen

Meine aktuelle Implementierung sieht aus wie der Code-Snippet:

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); 
} 

Wie Sie sehen, ich bin mit Paginierung Ansatz, damit ich einen Großteil der Daten geholt dann löschen und so weiter. Wie wird das in der Realität mit Hibernate erreicht? Danke für die Hilfe.

+2

Werfen Sie einen Blick auf: http://stackoverflow.com/questions/3492453/hibernate-and-delete-all. Könnte hilfreich sein. Der aktuelle Ansatz sieht ziemlich ineffizient aus, Sie müssen die gesamte Tabelle lesen und dann jeden Datensatz löschen, zu viele DB-Abfragen. –

Antwort

2

Versuchen Sie folgendes:

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

Sie nicht alle Datensätze holen müssen (oder Teile), um sie zu löschen. Schauen Sie auch here. Vielleicht wird es nützlich sein.

Leider löst dieser Ansatz keine Kaskadenentfernung aus. Vielleicht können Sie einen anderen Ansatz genehmigen. Erstellen Sie beispielsweise die zusätzliche Spalte "is_deleted", und legen Sie den Wert "true" fest, wenn sie entfernt wird. Danach können Sie einen Job in der Nacht planen. Dieser Job wird tatsächlich einen Teil dieser Benutzer durch Ihren Ansatz entfernen. Aber Sie müssen Ihren get \ fetch-Methoden eine Bedingung hinzufügen, um nur is_deleted = false-Benutzer zu berücksichtigen.

+0

Ich erkannte, dass mein Ansatz (in Frage beschrieben) eine geringe Leistung ist, weil zu viele Aufrufe von db. Also werde ich HSL für die Tabelle truncate verwenden. Aber mit diesem Ansatz im Fall der Assoziation wie viele-zu-viele bin ich gezwungen, native SQL-Abfrage zum Abschneiden der Assoziationstabelle zu verwenden. Danke Aliaksandr Budnikau und Vladimir Vagaytsev für Hilfe! – Dimon

1

Sie können tatsächlich hql oder jpl verwenden, vorausgesetzt, es gibt keine Kaskaden.

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