JPA Entities nicht thread safe? (Hibernate)

Status
Nicht offen für weitere Antworten.

mephi

Bekanntes Mitglied
Hi,

ich hab grad das Problem, dass ich 2 Klassen mit einer ManyToOne Beziehung hab. Ich hole mir Objekt A mit dem EntityManager und find() aus er DB, füge was in der Liste hinzu(Objekte von Klasse B) und speicher das dann mit merge(). Um das ganze auch realistisch zu simulieren starte ich 5 servlet aufrufe und dann schlägt es fehl wegen einer ConcurrentModificationException ..
Jeder Request bekommt seinen eigenen EntityManger und ein sysout hat mir auch bestätigt, dass die unterschiedlich sind. Die Objekte allerdings sind die selben. Also Objekt A gibt immer den selben HashCode. Muss ich selbst dafür sorgen dass mein Objekt und die Listen thread safe sind? Find ich ja schon etwas merkwürdig :(
 
M

maki

Gast
Servlets sind nicht threadsafe, sollte keine Geheimnis mehr sein ;)

Wer wirft denn die ConcurrentModificationException?
Eine Collection?
 

byte

Top Contributor
Zwei unterschiedliche EntityManager sollten nicht identische Objekte liefern, selbst wenn es die gleichen Datensätze sind. Du solltest nicht den Hashcode vergleichen (equals vs == ;) ), sondern Dir die Objekte im Debugger angucken (Eclipse zeigt Dir die Identität eines Objekts anhand einer ID, die kannst Du vergleichen).

Hast Du den 2nd Level Cache aktiviert?


Muss ich selbst dafür sorgen dass mein Objekt und die Listen thread safe sind?
JPA Objekte sind einfache POJOs. Die sind natürlich nicht thread-safe. Aber für gewöhnlich ist das auch kein Problem. Wenn Du Servlets schreibst, dann guck Dir das Open-Session-In-View Pattern an. Wenn Du das richtig implementierst, hast Du hier keine Probleme mit Concurrency.
 

mephi

Bekanntes Mitglied
maki hat gesagt.:
Servlets sind nicht threadsafe, sollte keine Geheimnis mehr sein ;)

Wer wirft denn die ConcurrentModificationException?
Eine Collection?

Also so genau steht das nicht da, die letzte Zeile in meinem Code ist em.merge(objA). Bevor ich meine ArraList mit java.util.collections.synchronizedList() ersetzt hab, flog der Fehler bei em.find(ObjAImpl.class, id)

*edit* ok, jetzt fliegts trotz synchronizedMap/Lists bei em.find() .. ist vll auch zufällig an welcher stelle er dann gleichzeitig auf eine list zugreift.
im stacktrace ganz oben steht: "at java.util.HashMap.onEntry(HashMap.java:214)"

byto hat gesagt.:
Zwei unterschiedliche EntityManager sollten nicht identische Objekte liefern, selbst wenn es die gleichen Datensätze sind. Du solltest nicht den Hashcode vergleichen (equals vs == ;) ), sondern Dir die Objekte im Debugger angucken (Eclipse zeigt Dir die Identität eines Objekts anhand einer ID, die kannst Du vergleichen).

Hast Du den 2nd Level Cache aktiviert?

nicht explizit, außer er ist standardmäßig aktiviert.
*edit*
es ist auch die selbe ID im debugger :-/

Muss ich selbst dafür sorgen dass mein Objekt und die Listen thread safe sind?
JPA Objekte sind einfache POJOs. Die sind natürlich nicht thread-safe. Aber für gewöhnlich ist das auch kein Problem. Wenn Du Servlets schreibst, dann guck Dir das Open-Session-In-View Pattern an. Wenn Du das richtig implementierst, hast Du hier keine Probleme mit Concurrency.

Ok, muss ich mir mal anschauen, ist das was spezielles von Hibernate?

Da die POJOs vom Framework verwaltet werden, dachte ich eigentlich dass die das auch thread safe machen.. war wohl ein Trugschluss.
 

byte

Top Contributor
mephi hat gesagt.:
Ok, muss ich mir mal anschauen, ist das was spezielles von Hibernate?

Da die POJOs vom Framework verwaltet werden, dachte ich eigentlich dass die das auch thread safe machen.. war wohl ein Trugschluss.

Bin mir relativ sicher, dass das Problem nicht Deine POJOs sind sondern der EntityManager. Der EntityManager ist nicht thread-safe, daher musst Du sicherstellen, dass bei jedem Request ein neuer EntityManager aufgemacht wird. Ist das bei Dir der Fall? Wenn die Exception bei em#find() kommt, dann wohl eher nicht.

Die POJOs sind zwar nicht thread-safe (das wäre auch schlimm), aber das ist auch nicht dein Problem. Denn wenn Du pro Thread :)= Request) einen eigenen EntityManager verwendest, dann erzeugen die auch jeweils eigene Identitäten der POJOs. Da können sich die Threads also gar nicht ins Gehege kommen.

Die Standard-Strategie ist, die Lebensdauer des EntityManager an den Request zu binden (siehe Open-Session-In-View). Das heisst, am Anfang des Request neuen EntityManager holen und diesen am Ende des Request zu schließen. Für gewöhnlich bindet man den EM an die Transaktion, so dass er beim commit() automatisch geschlossen wird.

Siehe: http://www.hibernate.org/hib_docs/entitymanager/reference/en/html_single/#transactions
 

mephi

Bekanntes Mitglied
Ich bin mir eigentlich sicher dass ich das alles umsetze. Ich hab eine System Klasse die threadlocal ist und die im Konstruktor einen neuen EM erstellt.

hab ein filter vor mein servlet geschalten:

Code:
		try {
			SystemImpl.getInstance().beginTransaction();
			System.out.println("Start Processing in  System... ");
			chain.doFilter(request, response);
			System.out.println("Ended Processing in  System...");	
			SystemImpl.getInstance().commitTransaction();
		} catch (Exception e) {
			e.printStackTrace();
			SystemImpl.getInstance().rollbackTransaction();
			((HttpServletResponse)response).sendError(500);
		} finally {
			SystemImpl.getInstance().close();
		}

system leitet hier die commit/begin und rollback aufrufe einfach an den EM weiter.



Code:
	public void beginTransaction() {
		this.em.getTransaction().begin();
	}
	
	public void commitTransaction() {
		this.em.getTransaction().commit();
	}
	
	public void rollbackTransaction() {
		this.em.getTransaction().rollback();
	}

	public void close() {
		this.em.close();	
	}
 

byte

Top Contributor
Erzeugst Du Dir über die EntityManagerFactory bei jedem Request einen neuen EntityManager?
 

mephi

Bekanntes Mitglied
ja, am anfang erstell ich eine factory und dann für jeden request einen neuen entitymanager
 

mephi

Bekanntes Mitglied
Ich glaub ich hab das problem. meine system klasse ist threadlocal und da erstell ich im konstruktor den EntityManager, aber im debugger hat der immer die selbe ID. Als ob mir die Factory immer den selben gibt.
mh und mein System hat auch die selbe ID... strange..


*edit* woa.. blöder fehler meinerseits. irgendwo hatte ich eine variable in der ich eine referenz auf meine systemklasse gespeichert hab. und da servlets ja nicht thread safe sind....
 

byte

Top Contributor
Ich würde Dein Konzept mit der System-Klasse nochmal überdenken. Mach es doch am besten gleich richtig und schreib DAOs, das übliche Pattern für diesen Anwendungsfall. Das DAO muss dann nur noch den richtigen EntityManager bekommen. Entweder, Du machst das händisch, indem Du Dir einen Filter schreibst, der am Anfang des Requests einen EntityManager erzeugen lässt über die Factory und diesen in den DAOs setzt. Oder Du benutzt gleich Spring...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Tabellen von nicht mehr vorhandenen Entities werden generiert Datenbankprogrammierung 0
megachucky JPA: Problem bei Mischung von nicht persistenten und bereits persistenten Entities Datenbankprogrammierung 3
D Entities mit Vererbung Datenbankprogrammierung 12
M MySQL probleme beim "Generate Tables from Entities" Datenbankprogrammierung 9
P JPA- Entities bleiben nach dem Löschen (unsichtbar?) in der Datenbank Datenbankprogrammierung 6
C Entities zwischen zwei PersistenceUnits tauschen Datenbankprogrammierung 5
W MySQL-Connector funktioniert nicht über WLAN -> MacOS Datenbankprogrammierung 10
M Meine Datenbank lässt sich mit meiner Methode nicht ändern Datenbankprogrammierung 1
P Reicht finally nicht um DB connections zu schließen in (altem) Java? Datenbankprogrammierung 4
D JOIN COLUMN wird nicht genommen Datenbankprogrammierung 2
Maxim6394 JPA / EclipseLink - n:m Beziehung wird nicht aktualisiert Datenbankprogrammierung 0
J SQLite Abfrage fehlerhaft - komme nicht weiter - please help. Datenbankprogrammierung 3
D Ich möchte dass ich nachdem man den Kommentar geschrieben hat den Kommentar in den Tabelle Bestellübersicht geschbeichert wird klappt nicht bei mir Datenbankprogrammierung 2
M Datenbank Zugraff nach Umwandlung in .jar-Datei nicht mehr möglich Datenbankprogrammierung 4
Auf MySql Datenbank zugreifen funktioniert nicht Datenbankprogrammierung 8
A Java DB Server lässt sich nicht starten Datenbankprogrammierung 3
B SQlite Datenbank, trotz Statements wurden nicht alle Zeilen erzeugt? Datenbankprogrammierung 35
T Datenzeilen werden nicht gelöscht Datenbankprogrammierung 6
Warum funktioniert MySQL nicht Datenbankprogrammierung 8
S Das printen der Ausgabe des Oracle-SQL-Statements in der Java-Eclipse-Konsole funktioniert nicht Datenbankprogrammierung 6
S Datenbankprogrammierung in Java unter NetBeans 12 funktioniert nicht! Datenbankprogrammierung 1
pkm PostgreSQL Kann mit mybatis einen Parameter für eine postgreSQL-Abfrage nicht übergeben. Datenbankprogrammierung 5
Davee SQLite SQLite Datenbank lässt sich nicht auf anderen PCs öffnen Datenbankprogrammierung 8
Watsoon Treiber wird in Intellij nicht geladen Datenbankprogrammierung 2
Kirby.exe PreparedStatement wird nicht ausgeführt Datenbankprogrammierung 5
rafi072001 MicroServices EurekaClient findet anderern EurekaClient nicht Datenbankprogrammierung 1
D JPA gleiche methode funktioniert an einer Stelle, an der anderen nicht Datenbankprogrammierung 3
Z Datenbank Choicebox wird nicht befüllt Datenbankprogrammierung 15
pkm PostgreSQL Auf eine Spalte kann aus einem Teil der SQL-Aussage nicht zugegriffen werden Datenbankprogrammierung 3
G MySQL JDBC Metadaten auslesen aus .accdb -> Primärschlüssel manchmal erkannt manchmal nicht Datenbankprogrammierung 3
C MySQL SQL Statement wir nicht ausgeführt Datenbankprogrammierung 11
N Sqlite DB mit Java wird auf Linuxsystem nicht gefunden Datenbankprogrammierung 9
pkm Tomcat Classloader findet bei JPA-Persistierung die Persistence Unit nicht. Datenbankprogrammierung 11
F Tabellen automatisch erstellen wenn sie nicht existieren Datenbankprogrammierung 6
J Netbeans 11 und Eclipse JPA 2.5 Entity wird nicht gefunden Datenbankprogrammierung 4
J Java fügt Datensätze ein aber diese werden nicht richtig abgefragt Datenbankprogrammierung 3
J Firebase KeepSynced funktioniert nicht Datenbankprogrammierung 0
OnDemand MySQL Trigger löst nicht aus bei Hibernate Update Datenbankprogrammierung 12
R HSQLDB ResultSet update aktualisiert DB, aber nicht das ResultSet Datenbankprogrammierung 2
platofan23 MySQL Java Programm findet Treiber für mySQL auf Debian-Server nicht? Datenbankprogrammierung 11
B MySQL Data Tools Plattform - "Database Connections" findet den Treiber nicht Datenbankprogrammierung 1
OnDemand One to Many bekomm es nicht hin Datenbankprogrammierung 7
L SQL-Statement INSERT INTO ON DUPLICATE KEY UPDATE funktioniert nicht Datenbankprogrammierung 5
OnDemand Update auf Mysql läuft nicht durch Datenbankprogrammierung 30
R jdbc-Zugriff Nicht erlaubt ? Datenbankprogrammierung 16
F H2 ObjectOptimisticLockingFailureException wird nicht geworfen Datenbankprogrammierung 0
R findet Derby.DB nicht !? Datenbankprogrammierung 5
I Datenbankverbindung Oracle DB klappt nicht - getConnection returned null Datenbankprogrammierung 8
X SQLite SQLite Programm beendet/führt nicht weiter aus Datenbankprogrammierung 12
P LDAP: Daten eintragen funktioniert nicht Datenbankprogrammierung 7
Ananaskirsche Datenbanktreiber kann nicht geladen werden Datenbankprogrammierung 2
S sun.jdbc.odbc.JdbcOdbcDriver wird nicht gefunden Datenbankprogrammierung 2
U Kann die Tabellen nicht finden Datenbankprogrammierung 0
M Java Datenbankanbindung funktioniert nicht Datenbankprogrammierung 4
C MYSQL kann wert nicht eintragen Datenbankprogrammierung 3
J Verbindung zu Derby Datenbank funktioniert nicht Datenbankprogrammierung 14
S MySQL MySQL will einfach nicht, bitte um Rat Datenbankprogrammierung 4
E Warum funktioniert das Erzeugen einer View nicht? Datenbankprogrammierung 1
E Warum kann mein SQL-File nicht in DB2 ausgeführt werden? Datenbankprogrammierung 1
M JDBC Tabellen mit Boolean Spalten können nicht erstellt werden. DB Updaten - wie? Datenbankprogrammierung 6
OnDemand Update table SET will nicht Datenbankprogrammierung 9
M DB-Zugriff funktioniert nach JAR-Erstellung nicht mehr Datenbankprogrammierung 3
J SQL-Statement Meine insert befehle funktionieren nicht und ich weiß nicht wo der fehler liegt Datenbankprogrammierung 5
S MySQL Speicher wird nicht freigegeben bei Datenbankabfragen Datenbankprogrammierung 6
L SQL Statement mit Switch-Case funktioniert nicht Datenbankprogrammierung 6
D MySQL Eingabe wird nicht übernommen... Datenbankprogrammierung 11
H Derby: SYSCS_UTIL.SYSCS_EXPORT_QUERY mit String Abfrage in wehre-Klausel nicht möglich Datenbankprogrammierung 3
F sun.jdbc.odbc.jdbcodbcdriver wird nicht gefuden Datenbankprogrammierung 3
L JTable-DB: Letzter wert wird nicht angezeigt. Datenbankprogrammierung 0
I Datenbank Verbindung geht nicht Datenbankprogrammierung 2
L MySQL App/Java Zugriff auf Mysql-DB funktioniert nicht Datenbankprogrammierung 1
I Kann nicht mit iiS DB Verbinden Datenbankprogrammierung 1
S Verbindungsaufbau zu MySql Datenbank nicht möglich Datenbankprogrammierung 3
D [xBaseJ] Datei kann nicht geöffnet werden Datenbankprogrammierung 2
N JDBC: rollback() bei Exception geht nicht!? Datenbankprogrammierung 1
K Datenbank wird bei Programmstart als .jar nicht mehr befüllt Datenbankprogrammierung 12
R Datenbankverbindung kann nicht hergestellt werden Datenbankprogrammierung 8
M Oracle Bekomme fertiges Tool nicht ans Laufen Datenbankprogrammierung 3
V Test H2-DB löscht nicht die IDs Datenbankprogrammierung 0
P PostgreSQL Java-Anwendung zählt rollbacks nicht Datenbankprogrammierung 0
M Finde einen eifachen Befehl nicht Datenbankprogrammierung 4
T MySQL Datetime wird auf Sekunden gerundet, soll es aber nicht Datenbankprogrammierung 2
P MySQL jpmdbc: Kann lesen aber nicht schreiben? Datenbankprogrammierung 3
1 MySQL Verbindung mit localhost als IP funktioniert, aber mit normaler IP nicht Datenbankprogrammierung 2
M Derby/JavaDB Neu geschriebener Eintrag per UPDATE lässt sich nicht unmittelbar abrufen Datenbankprogrammierung 2
J Datenbankeintag eines Warenkorbes funktioniert nicht Datenbankprogrammierung 4
AMStyles Kann Wert nicht speichern (MAX VALUE) Datenbankprogrammierung 9
M MySQL INSERT will einfach nicht funktionieren Datenbankprogrammierung 9
A Nach Export mysql Verbindung zur Datenbank nicht möglich, was tun? Datenbankprogrammierung 7
T SQL-Statement case when then klappt nicht Datenbankprogrammierung 4
B DB2 Hibernate findet Datenbank nicht Datenbankprogrammierung 18
J JDBC in Library|"Treiber konnte nicht geladen werden"" Datenbankprogrammierung 2
D MySQL Treiber konnte nicht geladen werden Datenbankprogrammierung 3
P JSF + H2 + TomEE + Hibernate/JPA Datenbank wird nicht angelegt Datenbankprogrammierung 3
C Db4o speichert verschachtelte Objekte nicht vollständig Datenbankprogrammierung 8
P SQL-Statement "Top 1" oder "limit" funktioniert nicht Datenbankprogrammierung 12
C Programm wird nach DB-Eintrag nicht weitergeführt Datenbankprogrammierung 5
R sqlite UPDATE wirkt nicht aus Java Datenbankprogrammierung 7
crashfinger jdbc-connection mit jre7 funktioniert nicht Datenbankprogrammierung 5
R PostgreSQL Tabellen hinzufügen, falls nicht vorhanden Datenbankprogrammierung 3

Ähnliche Java Themen

Neue Themen


Oben