-->
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.  [ 7 posts ] 
Author Message
 Post subject: Bidirektionales one-to-one mit foreign key generator
PostPosted: Tue Nov 29, 2005 7:10 am 
Newbie

Joined: Mon Nov 21, 2005 10:48 am
Posts: 7
Hibernate version:
2.1.8
Mapping documents:
<class name="Template" table="Template" lazy="true" >
<id name="id" type="long" column="id">
<generator class="native"/>
</id>
<property name="name" type="string" unique="true" />
<property name="description" type="string" />
<one-to-one name="templateDocument" class="TemplateDocument"
cascade="all" />
<many-to-one name="templateCategory" class="TemplateCategory"
not-null="true" />
<list name="templatePreviews" table="TemplatePreviews" lazy="true"
cascade="all-delete-orphan" inverse="true" >
<key column="template" />
<index column="page" />
<composite-element class="TemplatePreview">
<parent name="template" />
<property name="name" not-null="true" />
<property name="mimetype" />
<property name="data" type="binary" length="100000" />
</composite-element>
</list>
<set name="templatePages" lazy="true" cascade="all-delete-orphan"
order-by="pagenumber asc" inverse="true" >
<key column="template" />
<one-to-many class="TemplatePage" />
</set>
<set name="allocatedPersons" lazy="true" cascade="all-delete-orphan"
inverse="true">
<key column="template" />
<one-to-many class="AllocatedTemplate" />
</set>
</class>


<class name="TemplateDocument" table="TemplateDocument">
<id name="id" type="long" column="id">
<generator class="foreign">
<param name="property">template</param>
</generator>
</id>
<property name="mimetype" column="mimetype" type="string"/>
<property name="documentData" column="documentData" type="binary"
length="16777215" />
<property name="filename" column="filename" type="string"/>
<property name="size" column="size" type="long"/>
<one-to-one name="template" class="Template" constrained="true" />
</class>

Code between sessionFactory.openSession() and session.close():
Template template = new Template();
template.setName(newTemplateName);
template.setTemplateCategory(selectedTemplateCategory);

TemplateDocument templateDocument = new TemplateDocument();
templateDocument.setFilename(uploadedFile.getName());
templateDocument.setSize(uploadedFile.getSize());
templateDocument.setDocumentData(uploadedFile.getBytes());
templateDocument.setMimetype(uploadedFile.getContentType());
templateDocument.setTemplate(template);

template.setTemplateDocument(templateDocument);

templateDAO.saveTemplate(template); // entspricht session.save(template)

Name and version of the database you are using:
mysql Ver 12.22 Distrib 4.0.18, for suse-linux (i686)
The generated SQL (show_sql=true):
insert into akzidenzweb_Template (name, description, templateCategory) values (?, ?, ?)


Hallo,

ich habe das Problem, dass bei mir das Speichern von entsprechend
assoziierten Objekten nicht funktioniert.

Kann das sein, dass das darauf zurückzuführen ist, dass MySQL in der
Verison die ich einsetze keine Foreign Key Constraints unterstütz?



Gruß
Patrick


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 9:43 am 
Senior
Senior

Joined: Mon Aug 22, 2005 5:45 am
Posts: 146
nein, das kann nicht sein, denn das model von hibernate ist ausschließlich aufgrund der mapping-configuration definiert.

versuche mal mit dem Attribute cascade="save-update"

_________________
Please don't forget to give credit, if my posting helped to solve your problem.


Top
 Profile  
 
 Post subject: Solved: Bidirektionales one-to-one mit foreign key generator
PostPosted: Tue Nov 29, 2005 4:14 pm 
Newbie

Joined: Mon Nov 21, 2005 10:48 am
Posts: 7
Habe die Lösung gefunden warum beim Speichern eines Template Objektes das assoziierte TemplateDokument nicht gespeichert wurde:

Das ganze muss innherhalb einer Transaction ablaufen. Aber genau das hatte ich vorher in der DAO Methode save nicht drin.
Für die Zukunft bin ich schlauer.

Ich denke das war absoluter Anfängerfehler.


@axismundi
Sorry, meine Fehlerbeschreibung war ein wenig dürftig, wie mir gerade auffällt.
Bestätige mir einfach, dass Du das Problem dann auch erkannt hättest und ich gebe Dir nen Credit.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 4:28 pm 
Expert
Expert

Joined: Tue Oct 05, 2004 9:45 am
Posts: 263
@creator79
ich persönlich würde Dir davon abraten in der DAO-Methode die Transaktion zu starten und/oder ein "commit/rollback" zu machen.
Das führt immer dann zu Problemen, wenn Du innerhalb einer "Unit of work" mehrere Operationen innerhalb einer Transaktion ausführen willst/musst.

Das Transaktionshandling (inkl. damit verbundenem Exception-Handling) sollte daher außerhalb des DAOs stattfinden.

Oder habe ich Dich da gerade falsch verstanden?

gtx
curio


Top
 Profile  
 
 Post subject: Und noch was zu Lösen
PostPosted: Wed Nov 30, 2005 5:06 am 
Newbie

Joined: Mon Nov 21, 2005 10:48 am
Posts: 7
curio wrote:
ich persönlich würde Dir davon abraten in der DAO-Methode die Transaktion zu starten und/oder ein "commit/rollback" zu machen.
Das führt immer dann zu Problemen, wenn Du innerhalb einer "Unit of work" mehrere Operationen innerhalb einer Transaktion ausführen willst/musst.

Das Transaktionshandling (inkl. damit verbundenem Exception-Handling) sollte daher außerhalb des DAOs stattfinden.

Oder habe ich Dich da gerade falsch verstanden?


Die klare Antwort lautet Jein :-)

Meine Erfahrungen mit J2EE und Patterns sind nicht die Besten.
Ich denke mal, dass ich das DAO nicht als DAO im eigentlichen Sinne verwende. Also, dass ich quasi nur den Namen missbraucht habe.

Bei mir sehen die Methoden einer meiner DAO Klassen in etwa so aus:

Code:
public List getAllTemplates() throws HibernateException {
    return HibernateUtil.getSession().createQuery("from Template").list();
}

public void saveTemplate(Template t) throws HibernateException {
    Session s = HibernateUtil.getSession();
    Transaction tx = s.beginTransaction();
    s.saveOrUpdate(t);
    tx.commit();
}


Ein Servlet Filter schließt hinterher die Session - das ist glaube ich das Session-per-View Pattern oder so.

Nun zu der Frage/Antwort:
Wenn ich in der saveTemplate() Methode keine Transaktion starte, sondern direkt session.saveOrUpdate() verwende, dann wird das TemplateDocument (one-to-one) nicht gespeichert.

Ich habe Hibernate an der Stelle debugged - es wurde einfach kein Insert ausgeführt, aber im Cache waren das Template und das TemplateDocument Objekt mit den richtigen Werten belegt, aber halt nicht persistent - jedenfalls das TemplateDocument nicht.

Zur Verdeutlichung nochmal n bissl code:
Code:
Template template = new Template();
template.setName(newTemplateName);
template.setTemplateCategory(selectedTemplateCategory);

TemplateDocument templateDocument = new TemplateDocument();
templateDocument.setFilename(uploadedFile.getName());
templateDocument.setSize(uploadedFile.getSize());
templateDocument.setDocumentData(uploadedFile.getBytes());
templateDocument.setMimetype(uploadedFile.getContentType());
templateDocument.setTemplate(template);

template.setTemplateDocument(templateDocument);

templateDAO.saveTemplate(template);


Und die Mappings:
Code:
<class name="Template" table="Template" lazy="true" >
  <id name="id" type="long" column="id">
    <generator class="native"/>
  </id>
  <property name="name" type="string" unique="true" />
  <property name="description" type="string" />
  <one-to-one name="templateDocument" class="TemplateDocument" cascade="all" />
  <many-to-one name="templateCategory" class="TemplateCategory"
not-null="true" />
  <list name="templatePreviews" table="TemplatePreviews" lazy="true"
cascade="all-delete-orphan" inverse="true" >
    <key column="template" />
    <index column="page" />
    <composite-element class="TemplatePreview">
      <parent name="template" />
      <property name="name" not-null="true" />
      <property name="mimetype" />
      <property name="data" type="binary" length="100000" />
    </composite-element>
  </list>
  <set name="templatePages" lazy="true" cascade="all-delete-orphan"
order-by="pagenumber asc" inverse="true" >
    <key column="template" />
    <one-to-many class="TemplatePage" />
  </set>
  <set name="allocatedPersons" lazy="true" cascade="all-delete-orphan"
inverse="true">
    <key column="template" />
    <one-to-many class="AllocatedTemplate" />
  </set>
</class>


<class name="TemplateDocument" table="TemplateDocument">
  <id name="id" type="long" column="id">
    <generator class="foreign">
      <param name="property">template</param>
    </generator>
  </id>
  <property name="mimetype" column="mimetype" type="string"/>
  <property name="documentData" column="documentData" type="binary" length="16777215" />
  <property name="filename" column="filename" type="string"/>
  <property name="size" column="size" type="long"/>
  <one-to-one name="template" class="Template" constrained="true" />
</class>


So ging das dann - alles wurde gespeichert.

Jetzt habe ich aber ein anderes Problem:
Wenn ich nun noch TemplatePreview Objekte dem Template zuweise, erhalte ich folgende Fehlermeldung:
Code:
net.sf.hibernate.MappingException: Unknown entity class: x.y.z.model.TemplatePreview


Es stimmt, dass kein Mapping Dokument existiert.
Ich dachte, das sei bei Composite Elements nicht nötig.
Irgendwo im Hibernate Forum habe ich dann - Google sei Dank - ein Beispiel Mapping eines Spaniers oder so gefunden und gesehen, dass er solche composite elements nochmal als joined-subclass innerhalb der Klassendefinition definiert hat.

Das muß ich jetzt noch ausprobieren.

Oder hat da sonst noch jemand einen Tip?


Gruß
c79


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 30, 2005 5:33 am 
Expert
Expert

Joined: Tue Oct 05, 2004 9:45 am
Posts: 263
hmpf ... Du meinst Du startest und commitest Deine Transaktion in der "save"-Methode und machst das "rollback" ganz wo anders?
Oha ... na davon rate ich Dir ja nochmal wirklich ab.

Lieber die Transaktion, wie hier auch in diversen Dokumentationen beschrieben, außerhalb der DAOs starten und dort auch die Fehler etc. behandeln ...

Alles andere führt meiner Meinung nach nur dazu, dass früher oder später "Murks" in der Datenbank stehen bleibt und/oder die Applikation in einen Status der "Unwartbarkeit" kommt.

gtx
curio

btw: Ich habe nicht geschrieben, dass Du kein Transaktionshandling brauchst oder machen solltest ... ich meinte Du solltest das außerhalb Deiner DAOs machen.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 30, 2005 6:40 am 
Newbie

Joined: Mon Nov 21, 2005 10:48 am
Posts: 7
curio wrote:
hmpf ... Du meinst Du startest und commitest Deine Transaktion in der "save"-Methode und machst das "rollback" ganz wo anders?
Oha ... na davon rate ich Dir ja nochmal wirklich ab.

Lieber die Transaktion, wie hier auch in diversen Dokumentationen beschrieben, außerhalb der DAOs starten und dort auch die Fehler etc. behandeln ...

Alles andere führt meiner Meinung nach nur dazu, dass früher oder später "Murks" in der Datenbank stehen bleibt und/oder die Applikation in einen Status der "Unwartbarkeit" kommt.

gtx
curio

btw: Ich habe nicht geschrieben, dass Du kein Transaktionshandling brauchst oder machen solltest ... ich meinte Du solltest das außerhalb Deiner DAOs machen.


Okay, kam an.
Für den Design Hinweis gab's nen credit.

Das ganze ist eine Webapplikation, bei der ich zwangsweise nicht auf lange Transaktionen angewiesen bin.

Das Exception Handling habe ich bisher aussen vor gelassen, es wird aber noch implementiert. Ich möchte im Moment einfach alles an Fehlern sehen - so lernt man ja auch einiges ;-)

Trotzdem nochmals Dank für den Hinweis.

Gruß
c79


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.