2017-11-17 1 views
0

Ich habe eine Entität Anruf Firma und eine andere Entität Anruf Token.Wie zu vermeiden, schmutzig Überprüfung im Ruhezustand

1 Firma wird viele Tokens haben.

So in meine Firma Einheit, ich so etwas wie folgen haben:

@OneToMany(mappedBy = "companyId") 
public Set<Token> getTokens() { 
    return tokens; 
} 

Allerdings werde ich einige Logik während der Rückkehr haben, wird die Token-Liste vor Rückkehr, seine etwas wie Folge ändern:

Da ich den Wert in der Token-Liste ändere, wird jedes Mal, wenn ich das Firmenobjekt aus db mit Hibernate wähle, die Firmentabelle automatisch aktualisiert.

Basis meines Verständnisses ist dies ein Verhalten der Überprüfung von überwinterten Hibernate. Wenn Hibernate erkennt, dass sich dort etwas ändert, wird das Update für die Datenbank ausgeführt.

Gibt es eine Möglichkeit, dies zu vermeiden? Zum Beispiel, vielleicht rufen Sie einfach die bestehende Hibernate-Funktion auf, damit Hibernate weiß, dass die Token-Liste verschmutzt ist, und das Update wird nicht ausgeführt.

Ja, ich weiß, dass die Filterlogik in getTokens() nicht geeignet ist. Die richtige Filterlogik sollte nicht auf Entitätsebene angewendet werden. Aber aufgrund der Tatsache, dass es derzeit viele Orte gibt, die diese Methode verwenden, wenn ich mich in dieser Entity-Ebene ändere, wird es andere beeinflussen und wenn ich auch einen anderen Ort ändere, muss die gesamte Anwendung erneut getestet werden.

So versuche ich einen besseren Weg zu finden.

+1

Ein alternativ Sie tun können, ist, anstatt die Originaldaten zu verändern, Kopie der ursprünglichen Daten erstellen und dann Ihre Logik auf kopierten Daten durchführen und dann kopierten Daten zurück. –

Antwort

1

Was Sie eigentlich wollen, ist, den Ruhezustand von Auto flushing zu verhindern.

Siehe hibernate docs:

Flushing ist der Prozess, die darunter liegenden persistent Speicher mit Persistable Zustand der Synchronisierung im Speicher gehalten.

Eine Lösung für dieses Problem ist, indem FlushMode.MANUAL die Standardkonfiguration von FlushMode von automatisch auf manuell zu ändern. Auf diese Weise hört der Dirty-Check-Mechanismus auf, die oben erwähnte Synchronisation zu verursachen.

Obwohl die Session immer nur geleert wird, wenn Session.flush() explizit von der Anwendung wie in der hibernate documentation beschrieben aufgerufen wird.

Hier muss erwähnt werden, dass, wenn Sie die vorgeschlagene Lösung, die Sie den Preis der expliziten Spülung zahlen müssen folgen, was bedeutet, dass Sie die Session.flush() Methode jedes Mal, wenn Sie möchten ausdrücklich Anruf müssen etwas auf der Datenbank begehen.

Lesen Sie here einige nützliche Material in Bezug auf FlushMode wie offiziell in Hibernate Dokumentation dokumentiert wurden.

UPDATE:
Diese Lösung auf der Session gilt, also wenn Sie diese nur auf die spezifische Entität anwenden möchten, sollten Sie versuchen, zwei Methoden zu erstellen.Eine für die Einstellung auf MANUELL und eine für die Rückkehr zur Standardautomatik. Auf diese Weise ändern Sie Ihren Wert nach der MANUELLEN Einstellung, um ein Spülen zu verhindern, und anschließend setzen Sie ihn auf den Standardwert zurück, um die anderen Objekte nicht zu beeinflussen.
Vielleicht die folgende Implementierung helfen:

@Autowired 
private SessionFactory sessionFactory; 


@OneToMany(mappedBy = "companyId") 
public Set<Token> getTokens() { 
    setFlushModeManual(); 
    tokens.remove(token); 
    setFlushModeAuto(); 
    return tokens; 
} 

private void setFlushModeManual() { 
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.MANUAL); 
} 

private void setFlushModeAuto() { 
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO); 
} 
+0

Ya, ich muss explizit die Session.flush() aufrufen, wenn ich dies tue. Eigentlich möchte ich nur die schmutzige Überprüfung im Winterschlaf bei diesem Modul vermeiden, aber keine anderen Module. Ich versuche einen Weg zu finden, nur in dieser Firma zu gelten.getTokens(), nicht sicher ist es möglich oder nicht. –

+0

Ich habe meine Antwort mit einem Workaround aktualisiert. Probieren Sie es aus und sehen Sie, ob dies hilfreich ist. –

+0

Hi @Anastasios, sorry noch nicht wirklich darauf verstehen. Die 'setFlushModeManual()' und 'setFlushModeAuto()' Methode, wie wird es funktionieren? Ich habe keinem Term oder einer Variable irgendeinen 'FlushMode' zugewiesen, wie wird das Programm verstehen, dass der getTokens Teil manuell oder automatisch wird? Ich bin ziemlich neu im Winterschlaf. –

Verwandte Themen