-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: Hibernate Caching
PostPosted: Mon Dec 05, 2005 6:23 am 
Beginner
Beginner

Joined: Mon Dec 05, 2005 4:15 am
Posts: 36
Ich bin noch Anfänger in Hibernate, und mache meine erste Anwendung. Es gibt eine mehrere-zu-mehreren Bezieheung zwischen der Tabelle Personen und der Tabelle Betriebe. Ich mache Mappings für die zwei Tabellen sowie für die Tabelle "Beziehungen", bei der der primäre Schlüssel aus PersonenID und BetriebsID besteht. Diesen Schlüssel deklariere ich in der Mapping-Datei als composite key mit one-to-one beziehungen zu jeweiliger Entität.

Wenn ich mal die Inhalte der Beziehungen-Tabelle lese, kriege ich ein Objekt "Beziehung", welches die Objekte Person(ID=200, Name="Mustermann" und Betrieb(ID=500, Name="Musterfirma GmbH") beinhaltet. Dann gehe ich ins Pflegemodule für Personen, lese das Objekt Person mit dem Namen Mustermann und ändere den Namen auf "Müller". Wenn ich dann aber wieder die Beziehungen-Tabelle lese, bekomme ich bei dem Datensatz das alte Person Objekt mit dem Namen "Mustermann", obwohl dieses Objekt gerade geändert wurde! Um dieses Problem umzugehen, rufe ich die clear() Methode des Session - Objektes, doch dies ist keine gute Lösung. Wie kann ich die Hibernate-Sitzung veranlassen, das Objekt im Cache zu aktualisieren? Die Aufrufe vom flush() oder evict() gerade nach dem Speichern bewirken sich nuf auf die Personen-Tabelle, und für die Beziehung holt Hibernate immer das alte Objekt, obwohl jede Beziehung eine Referenz auf das "Person"-Objekt hat!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 05, 2005 8:51 am 
Beginner
Beginner

Joined: Mon Oct 24, 2005 9:46 am
Posts: 22
Location: Germany
poste doch bitte die Mappings und etwas (pseudo-)Code, ansonst kann man dir nicht wirklich gut helfen


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 05, 2005 5:12 pm 
Beginner
Beginner

Joined: Mon Dec 05, 2005 4:15 am
Posts: 36
Die Mappings:

person.hbm.xml:
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="mypackage.Person" table="person">

<id name="pid" type="string" unsaved-value="null" >
<column name="pid" sql-type="char(16)" not-null="true"/>
<generator class="uuid"/>
</id>


<property name="name"/>
<property name="vorname"/>
</class>

</hibernate-mapping>


betrieb.hbm.xml:

<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="mypackage.Betrieb" table="betrieb">

<id name="bid" type="string" unsaved-value="null" >
<column name="bid" sql-type="char(16)" not-null="true"/>
<generator class="uuid"/>
</id>


<property name="name"/>
<property name="name2"/>

<property name="strasse"/>
<property name="plz"/>
<property name="ort"/>
</class>

</hibernate-mapping>


beziehung.hbm.xml:

<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="mypackage.Beziehung" table="beziehungen">

<composite-id name="schluessel" class="mypackage.Beziehung$Schluessel">

<key-many-to-one name="person" column="pid" class="mypackage.Person"/>
<key-many-to-one name="betrieb" column="bid" class="mypackage.Betrieb"/>
</composite-id>

<property name="erstellt_von"/>

<property name="erstellt_am"/>

</class>


POJO für die Klasse Beziehung sieht so aus:

public class Beziehung{

public static class Schluessel implements Serializable {

private Betrieb b;
private Person p;
public Betrieb getBetrieb () {
return b;
}
public void setBetrieb (Betrieb b ) {
this.b = b;
}
public Person getPerson () {
return p;
}
public void setPerson (Person p) {
this.p = p;
}
}

private Schluessel schluessel;

public Schluessel getSchluessel () {
return schluessel;
}
public void setSchluessel (Schluessel schluessel) {
this.schluessel= schluessel;
}



So speichere ich eine Person:

public class PersonDAO{
...

public void speichere(Person p) {
Transaction tx= ses.beginTransaction();
ses.update(p);
tx.commit();
}

und so hole ich die Liste der Beziehungen:

public class BeziehungenDAO{
...
public List holeAlleBeziehungen()
ses.clear(); //
Transaction tx= ses.beginTransaction();
Query query = ses.createQuery("from Beziehung");
List l = query.list();
tx.commit();

return l;
}


und dann verwende ich diese Liste, um die Daten anzuzeigen. Nachdem ich eine Person-Entität mit der methode speichere(p) speichere, ohne die Zeile ses.clear(); gibt mir der Ausdruck
((Beziehung)bezDAO.holeAlleBeziehungen().get(2)).getSchluessel().getPerson(); ein Objekt mit alten Daten zurück, ein Objekt mit demselben Inhalt wie vor dem Speichern.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 05, 2005 7:14 pm 
Expert
Expert

Joined: Tue Dec 07, 2004 6:57 am
Posts: 285
Location: Nürnberg, Germany
Kurze Zwischenfrage: warum mappst du das nicht einfach mit ner many-to-many relation?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 06, 2005 8:06 am 
Beginner
Beginner

Joined: Mon Dec 05, 2005 4:15 am
Posts: 36
MikePloed wrote:
Kurze Zwischenfrage: warum mappst du das nicht einfach mit ner many-to-many relation?


Ich könnte many-to-many relation einsetzen, wenn ich die Tabelle 'Beziehungen' explizit nicht ansprechen würde. Doch ich muss auch die Felder "erstellt_von" und "erstellt_am" beim Speichern eines Datensatzes setzen, deshalb musste ich auch für die Tabelle 'Beziehungen' ein Mapping und ein POJO anlegen. (in meiner Datenbank werden keine Triggers eingesetzt.)

oder mache ich was falsch und es gibt einen besseren Weg?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 06, 2005 8:55 am 
Beginner
Beginner

Joined: Mon Oct 24, 2005 9:46 am
Posts: 22
Location: Germany
In diesem Fall ist es wohl angebracht in dem zwischengelagerten 'Beziehungen' pojo einfach 2 (bidirektionale) one-to-many's einzufügen


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 08, 2005 9:15 am 
Beginner
Beginner

Joined: Mon Dec 05, 2005 4:15 am
Posts: 36
ich habe festgestellt, dass dieses komische Effekt tritt nur auf, wenn ich versuche, einen Datensatz aus der Tabelle 'Person' zu löschen, welcher über Foreign Key mit einem Datensatz aus der Beziehungen-Tabelle verknüpft. Dann kommt es zu einer Hibernate Exception, welche fange ich auf und mache den Rollback. Wenn ich danach gerade diesen Datensatz ändere, er wird zwar geändert, die entsprechende 'Beziehungen' Entität wird aber dabei nicht aktualisiert.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 16, 2005 7:41 am 
Beginner
Beginner

Joined: Mon Dec 05, 2005 4:15 am
Posts: 36
Noch seltsamer ist es, wenn ich die Bezeihung bidirektional mache.

Dann, beim Versuch, eine Person zu löschen, welche mit einer "Beziehung" verknüpft ist, kommt es (wie erwartet) zu einem Fehler:

Hibernate: update beziehungen set pers_id=null where pers_id=?
Could not execute JDBC batch update: Aktualisieren von ("BEZIEHUNGEN"."PERS_ID") zu NULL nicht möglich

ich fange die Exception auf und mache Rollback.
Wenn ich danach versuche, diese Person zu modifizieren, dann scheitert es an dem Aufruf von der get-Methode:
Person p = (Person)s.get(Person.class, id);

Exception in thread "main" org.hibernate.ObjectDeletedException: The object with that id was deleted: [pojo.Person#1]

Und das, obwohl der Datensatz physikalisch nicht gelöscht wurde!

Meine Löschen-Methode sieht folgendermaßen aus:

public void personLoesche(Serializable id, Session s){
Transaction t = s.beginTransaction();
try{
Person p = (Person)s.get(Person.class, id);
s.delete(p);
t.commit();
}catch(Exception e){
t.rollback();
}
}

Könnte mir jemand dieses Effekt erklären?
Danke.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.