Here's what I like: Define a service interface which specifies the high-level business operations. The implementation of that interface would be in terms of the business/domain model objects. I'd keep hibernate code out of those objects to the degree that's possible.
The trick, then, is to use a dynamic proxy in front of the object implementing the service interface. The "client" of the service interface thinks it's dealing directly w/ some object that implements that interface, when in fact it's got an instance of a proxy. In the "invoke" method of the proxy class (i.e. the one which implements InvocationHandler), put the code to initiate and commit/abort transactions, log method entry & exit, handle exceptions, etc. So now that's done for all business operations in a single place, and every time you tweak the service implementation or add a new method, you don't have to have all this boilerplate code. Put connection/session info which is established in the proxy's invoke method in a ThreadLocal which can be used by the layer which deals w/ hibernate. I've done this both with in-process services and service interfaces implemented as stateless session beans. FWIW... Donnie -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Behalf Of Ampie Barnard Sent: Friday, November 15, 2002 2:22 AM To: [EMAIL PROTECTED] Subject: RE: [Hibernate] Using hibernate - best practices I like the services-layer idea, but also have to agree that it leads to repetitive code. In our system, we have implemented the service layer as session beans. The transaction management is taken care of by the container. But we still have the repititive try{ opensession(); }catch(Exception e){ rolbackSession();throw e; }finally{ closession(); } I have also simply sacrificed session propagation from one session bean to another. If someone were to implement the sessionFactory as a JCA connector, all of this code would become the responsibility of the container. It would also do the propagation of transaction contexts. As an interim solution, someone could perhaps implement a "stateless" version of the session factory that automatically flushes and closes itself when a transaction commits, and closes when the transaction rolls back. Am I on the right track here? -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Behalf Of Jozsa Kristof Sent: 15 November 2002 01:02 To: Urberg, John Cc: [EMAIL PROTECTED] Subject: Re: [Hibernate] Using hibernate - best practices On Thu, Nov 14, 2002 at 01:36:13PM -0600, Urberg, John wrote: . > The InvoiceRepository would be implemented like this: > > public class HibernateInvoiceRepository { > public void setDatabase(Database database) { _database = > (HibernateDatabase) database; } > public List getOverdueInvoices() { > return database.getSession().find("<hibernate query>"); > } > public void update(Object object) { > database.getSession().saveOrUpdate(object); > } > } > And where do you close those opened sessions using this design? Also, where did you find a place to implement transaction handling, including joining into existing transactions if possible? I have my own pieces of ideas how to implement a design for Hibernate, but I'm fighting with the questions listed above too. Got some workaround, but kinda far from being perfect.. Mainly I used Ralf's third possible solution from these: > > * Put everything into the domain classes. > > * Implement something like a "Home" interface > > * Implement some sort of component-like / "Service" interface .having a layer of 'service-like' components in charge of database-related operations, which either use Hibernate (98%) or plain JDBC pulling the connection from a Hibernate session. These components are always pulled by the upper layer from a plain component pool, which I implemented myself. But mentioning one returning problem, I have *LOTS* of repeated code parts like these: Session session = null; Transaction tx = null; try { session = Hibernator.getSession(); // my custom class which keeps the sessions and initializes Hibernate tx = session.beginTransaction(); .. .. tx.commit(); } catch (Exception e) { logger.error (<blah/>), e); tx.rollback(); // rethrow business-exception if suitable } finally { if (session != null) session.close(); } These piece of codes are repeating in almost ALL of the Service classes' business methods, are just flooding all the logic badly :( (ok, tx handling is missing from this where i'm doing read-only operations, but still..) I also have some part-solution related to joining to existing transactions, but I find it snappy too. So, as I said, I don't feel my design good at all.. just couldn't find out any better for the moment. Therefore, I'd be very happy and thankful to read about others experiences and concrete architecture/design plans. Regards, dyn -- .Digital.Yearning.for.Networked.Assassination.and.Xenocide ------------------------------------------------------- This sf.net email is sponsored by: To learn the basics of securing your web site with SSL, click here to get a FREE TRIAL of a Thawte Server Certificate: http://www.gothawte.com/rd524.html _______________________________________________ hibernate-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/hibernate-devel ------------------------------------------------------- This sf.net email is sponsored by: To learn the basics of securing your web site with SSL, click here to get a FREE TRIAL of a Thawte Server Certificate: http://www.gothawte.com/rd524.html _______________________________________________ hibernate-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/hibernate-devel ------------------------------------------------------- This sf.net email is sponsored by: To learn the basics of securing your web site with SSL, click here to get a FREE TRIAL of a Thawte Server Certificate: http://www.gothawte.com/rd524.html _______________________________________________ hibernate-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/hibernate-devel