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