JPA Verständnisproblem - persist(), merge(), getReference()

Status
Nicht offen für weitere Antworten.

mephi

Bekanntes Mitglied
Ich check gerade nicht ganz wie ich ein eigentlich simples Problem lösen soll..

Ich bekomm in meinem Servlet eine userId. So nun stellt sich die Frage ob es den User in der DB schon gibt oder nicht. getReference liefert ja leider nicht null zurück sondern wirft eine Exception wenn es den User nicht gibt. Ich könnte einfach ein neues User Objekt anlegen, aber dann muss ich wieder unterscheiden ob ich merge() aufrufe falls es den User schon gibt bzw nichts wenn sich nichts an ihm verändert oder persist() ..
Rufe ich nur merge() auf under User war noch nicht in der DB vorhanden, gibts spätestens Probleme wenn ich den User bei einem neuen Session objekt mit setUser() übergebe und die Session per persist() speichern will. Dann kommt die Fehlermeldung: "not-null property references a null or transient value:"

Irgendwie check ich nicht wie ich damit arbeiten soll. Das sind ja bisher nur einfache Tests die ich irgendwie hinbiegen kann. Aber ich weiß nicht wie ich eine fehlerfreie Anwendung schreiben soll.

Oder muss ich immer Queries starten um zu schauen was existiert? Dachte genau das nimmt mir ein Persistenz Framework ab
 

byte

Top Contributor
mephi hat gesagt.:
getReference liefert ja leider nicht null zurück sondern wirft eine Exception wenn es den User nicht gibt.
Und wo genau liegt das Problem, die Exception zu fangen und dann das Objekt neu anzulegen?
Ich benutze den EntityManager nicht sondern arbeite direkt mit der Hibernate Session (bzw. HibernateTemplate in Spring). Dort gibts ne Methode saveOrUpdate(), die entweder das Objekt updated oder - falls es noch nicht existiert - das Objekt anlegt.
 
M

maki

Gast
Warum nicht die find Methode nutzen?

Genau dafür ist sie ja schliesslich da.
 

mephi

Bekanntes Mitglied
byto hat gesagt.:
mephi hat gesagt.:
getReference liefert ja leider nicht null zurück sondern wirft eine Exception wenn es den User nicht gibt.
Und wo genau liegt das Problem, die Exception zu fangen und dann das Objekt neu anzulegen?
Ich benutze den EntityManager nicht sondern arbeite direkt mit der Hibernate Session (bzw. HibernateTemplate in Spring). Dort gibts ne Methode saveOrUpdate(), die entweder das Objekt updated oder - falls es noch nicht existiert - das Objekt anlegt.

wie im anderen thread mal erwähnt möchte ich da ja variabel sein und mich noch nicht auf ein framework festlegen

maki hat gesagt.:
Warum nicht die find Methode nutzen?

Genau dafür ist sie ja schliesslich da.

danke, die methode hab ich natürlich gekonnt übersehen :roll: :oops:


*edit*
wenn ich den thread schon offen hab:

wir würdet ihr folgendes lösen?

ich hab ein event objekt mit werten wie eventype, payload usw. diese felder zusammen sind unique. aber um es einfacher zu handeln würde ich gern eine automatische id vergeben die dann auch der PK ist. wenn nun die daten für ein event reinkommen(also type,payload etc) möcht ich die referenz für diesen event haben und keinen neuen anlegen(was ja auch nicht geht). hab mir überlegt die 4 felder zum PK zu machen und die ID einfach nur unique, oder wäre das eher ungeschickt?
 

byte

Top Contributor
Composite Keys sind gruselig, würde ich auf keinen Fall machen. PK sollte immer ein Kunstschlüssel sein!

Mach doch einfach ein @UniqueConstraint auf die entsprechenden Spalten.
 

mephi

Bekanntes Mitglied
Das habe ich gemacht. Aber in meinem Servlet bekomm ich nur die Daten des Events und nicht den Key dazu. Hier müsste ich dann per Query mit den Daten die Id des Events holen oder ihn gegebenfalls neuanlegen? Oder gibts hier eine andere Möglichkeit die direkt vom Framework angeboten wird?
 

byte

Top Contributor
Die ID holen? Du meinst die Entity holen!? Ja, Du musst dann mit den Werten dann das Objekt per Query holen. Um Queries kommst Du auch bei ORMs selten herum. Aber mit den richtigen UniqueConstraints auf einem Table ist das Query sehr schnell.
 

byte

Top Contributor
Naja, irgendwo machst Du ja mit dem PersistenceManager Deine DB-Operationen, um Deine POJOs zu laden und zu speichern. Für gewöhnlich schreibt man sich eine DAO Schicht für diese Zwecke. Wo machst Du denn diese Aufrufe derzeit? Direkt im Servlet? Davon ist abzuraten.
 

mephi

Bekanntes Mitglied
Ich hab eine "System" Klasse als Threadlocal implementiert, da gibts Methoden wie "loadEvent" und "saveEvent". Ich hab mir überlegt in diesen Methoden direkt gleichnamige Methoden im PersistenceManager aufzurufen wo ich dann die DB operationen mit dem EnitityManager mache. So wäre die Schicht komplett getrennt.
 

mephi

Bekanntes Mitglied
So ich nutz den Thread weiter :)

Bei einer ManyToOne Beziehung in der einen Klasse und eine OneToMany Beziehung in der anderen..

Code:
	@OneToMany(targetEntity=SessionImpl.class, mappedBy="user")
	private List<ISession> sessionList = new ArrayList<ISession>();
Code:
	@ManyToOne(targetEntity=UserImpl.class)
	@JoinColumn(nullable=false)
	private IUser user;

wenn ich nun in der session den user setze, dann ist er nicht automatisch auch in der sessionList vom user.
wie gehe ich da nun vor? von hand die session beim user adden oder muss ich meine transaction erstmal committen und dann den user neuladen??
irgendwie ist mir die ganze vorgehensweise noch etwas unverständlich :)
 
M

maki

Gast
Bi-direktionale Beziehungen sind komplexer als Uni-direktionale, die Mapping annos beziehen sich darauf, was passiert, wenn die Objekte aus der DB geladen/gespeichert werden, nicht darauf was passiert wenn du Zuweisungen an die Objekte machst.
Mit anderen Worten:
von hand die session beim user adden
Ja, so etwas muss man "von hand" machen, denn das ist nicht worum es bei JPA geht ;)

Bi-direktionale Assos haben ihren Preis, am besten eines der Objekte kümmert sich darum, das beides gesetzt wird.

Gehören Sessions eigentlich zu deiner Domäne?
 

mephi

Bekanntes Mitglied
In dem Fall schon. Die übernehm ich einfach vom request und die dient in dem Fall als Gruppierung von Events. Könnt ich auch über die Zeit machen, aber das Design hab ich nicht allein aufgestellt :)
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben