From: Urberg, J. <ju...@ve...> - 2002-11-14 19:36:29
|
Ralf, This is what I have done: 1) Created a Database interface that has common database stuff like connect, commit, rollback, lookup, update, delete, etc. 2) Created "Repository" interfaces that have any database functionality for a specific domain object or group of domain objects (I got this idea from http://www.domainlanguage.com/). If you want to be really safe, you should put the update and delete in the repository too. 3) Created implementations of database and repository interfaces using Hibernate. Example: Lets say I have an Invoice object that contains InvoiceLine objects. I have a requirement to load overdue invoices and do something to them. I would end up with code like this: InvoiceRepository repository = database.getRepository(InvoiceRepository.class); List overdueInvoices = repository.getOverdueInvoices(); // gets invoices and associated objects database.beginTrans(); for (Iterator i = overdueInvoices.iterator(); i.hasNext(); ) { Invoice invoice = (Invoice) i.next(); invoice.doSomething(); repository.update(invoice); } database.commit(); 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); } } Then later, if you need to change your application to work against a database not supported by Hibernate, you could implement repositories against it. Hope this helps, John > -----Original Message----- > From: Ralf E. Stranzenbach [mailto:mo...@re...] > Sent: Thursday, November 14, 2002 12:53 PM > To: hib...@li... > Cc: mh...@be...; Ralf Stranzenbach Edmund > Subject: [Hibernate] Using hibernate - best practices > > Hi, > > at the moment i spent some time on a small application using hibernate. > I've did most of the domain's modeling and implementation. Now i have to > decide where to place the database (say hibernate) dependent code. > > * Put everything into the domain classes. > * Implement something like a "Home" interface > * Implement some sort of component-like / "Service" interface > > Domain Classes with database access > This implementation strategy seems to be the simplest one of all. Database > access is at most implemented as static methods of the domain class. But > unfortunately this establishes a very strong link between the domain > classes and the persistence provider. If i decide to change the > persistence provider for any reason, i have to modify all domain classes. > > Implementation of a Home-Interface > This solution seems to keep things moderate simple. Each domain class > (e.g. Actor) owns one associated "home interface" (e.g. ActorHome). Using > some Factory it is possible to obtain a specific implementation (e.g. > ActorHomeHibernateImpl) of that interface. All communication with the > underlying persistence provider is channeled through this interface. The > domain classes will be (almost) free of code dealing with the database > (Lifecycle etc. seems to be still a problem). In this case i have to > provide some abstraction for the persistence services (update(), delete(), > TX-management). > > Implementation of Service like structures > This is more or less the same idea like above but with coarser > granularity. In this case i think about interfaces covering note single > domain classes but semantic groups of them. In this way something that > smells like a "component" (with its own lifecycle) could be implemented. > Using this strategy the Service-Interface would behave also as a service > provider for the domain classes. But this design could offer some chances > to reimplement parts of the application using different persistence > providers (requires the domain classes using the Service-Interface if > crossing "component" borders). > > At this moment i'm not sure wich basic design i should use. Please drop me > some notes about this topic. > * Which is your preffered strategy? > * Why have you choosen your way? > * What are the benefits or the drawbacks? > > regards, > Ralf E. Stranzenbach |
From: Ampie B. <amp...@mw...> - 2002-11-15 07:13:15
|
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: hib...@li... [mailto:hib...@li...]On Behalf Of Jozsa Kristof Sent: 15 November 2002 01:02 To: Urberg, John Cc: hib...@li... 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 hib...@li... https://lists.sourceforge.net/lists/listinfo/hibernate-devel |
From: Gavin K. <ga...@ap...> - 2002-11-16 14:18:08
|
The way I handle this is to use a command framework, where there is a session bean that acts as a command execution context. exception handling like this can then be built (once) into either the command bean or session bean. I don't find it necessary to have a different session bean remote method for each application task. ----- Original Message ----- From: "Ampie Barnard" <amp...@mw...> To: <hib...@li...> Sent: Friday, November 15, 2002 6:21 PM 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: hib...@li... > [mailto:hib...@li...]On Behalf Of Jozsa > Kristof > Sent: 15 November 2002 01:02 > To: Urberg, John > Cc: hib...@li... > 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 > hib...@li... > 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 > hib...@li... > https://lists.sourceforge.net/lists/listinfo/hibernate-devel |
From: Gavin K. <ga...@ap...> - 2002-11-16 14:21:27
|
>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. I am looking into implementing a JCA connector, by the way.... |
From: Urberg, J. <ju...@ve...> - 2002-11-15 13:32:01
|
>> The InvoiceRepository would be implemented like this: >> [code to load invoices] > 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? That's the responsibility of the database object. Code will usually look something like this: SomeRepository someRepository = database.getRepository(...); AnotherRepository anotherRepository = database.getRepository(...); database.startTrans(); try { someRepository.update(object); anotherRepository.update(object); database.commit(); } catch (Exception e) { database.rollback(); } All the code for dealing with sessions and transactions is safely tucked away in the database implementation. > These piece of codes are repeating in almost ALL of the Service classes' > business methods, are just flooding all the logic badly :( I'm not sure how you get around the whole transaction thing unless you're in a J2EE server that does that automatically. If you want to get rid of the boilerplate code, you could do something like this: public class Database { <...> public void inTransactionDo(Runnable doRun) { Session session = null; Transaction tx = null; try { session = Hibernator.getSession(); tx = session.beginTransaction(); doRun.run(); tx.commit(); } catch (Exception e) { logger.error (<blah/>), e); tx.rollback(); } finally { if (session != null) session.close(); } <...> } Then your business methods would look like this: database.inTransactionDo(new Runnable() { public void run() { <...business logic here...> } } Regards, John Urberg |
From: Hiram C. <hch...@jb...> - 2002-11-16 04:50:57
|
First time post... I like hibernate. I want to use it more with the Aspect Framework that I'm build for JBoss. Anyways, here is a way a Jboss aspect could help simplify things: You would use an interceptor that had an invoke method that looked something like: class HibernateInterceptor { ... public Object invoke(AspectInvocation invocation) throws Throwable { HibernateContext oldHC = getHibernateContext(); HibernateContext hc = null; if( oldHC==null || oldHC.sessionFactory != sessionFactory ) { hc = new HibernateContext(); hc.sessionFactory = sessionFactory; hc.session = sessionFactory.openSession(); hc.transaction = hc.session.beginTransaction(); setHibernateContext(hc); } try { Object rc = invocation.invokeNext(); if( hc != null ) hc.transaction.commit(); return rc; } catch ( Throwable e ) { if( hc != null ) hc.transaction.rollback(); throw e; } finally { if( hc != null ) hc.session.close(); setHibernateContext(oldHC); } } .. } class RuleListAction implemetns IRuleListAction { .. public String doDelete() throws Exception { Session session= HibernateInterceptor.getSession(); RuleList mo = (RuleList) session.load( RuleList.class, id ); session.delete(mo); return SUCCESS; } .. } so that if you have DynamicProxy x with the HibernateInterceptor in the invocation chain then you could just do a: IRuleListAction x = (IRuleListAction )AspectFactory(new RuleListAction()); x.doDelete() Regards, Hiram > -----Original Message----- > From: hib...@li... > [mailto:hib...@li...]On Behalf Of Urberg, > John > Sent: Friday, November 15, 2002 8:30 AM > To: 'Jozsa Kristof' > Cc: hib...@li... > Subject: RE: [Hibernate] Using hibernate - best practices > > > >> The InvoiceRepository would be implemented like this: > >> [code to load invoices] > > > 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? > > That's the responsibility of the database object. Code will usually look > something like this: > > SomeRepository someRepository = database.getRepository(...); > AnotherRepository anotherRepository = database.getRepository(...); > database.startTrans(); > try { > someRepository.update(object); > anotherRepository.update(object); > database.commit(); > } catch (Exception e) { > database.rollback(); > } > > All the code for dealing with sessions and transactions is safely tucked > away in the database implementation. > > > These piece of codes are repeating in almost ALL of the Service classes' > > business methods, are just flooding all the logic badly :( > > I'm not sure how you get around the whole transaction thing > unless you're in > a J2EE server that does that automatically. If you want to get rid of the > boilerplate code, you could do something like this: > > public class Database { > <...> > public void inTransactionDo(Runnable doRun) { > Session session = null; > Transaction tx = null; > try { > session = Hibernator.getSession(); > tx = session.beginTransaction(); > doRun.run(); > tx.commit(); > } catch (Exception e) { > logger.error (<blah/>), e); > tx.rollback(); > } finally { > if (session != null) session.close(); > } > <...> > } > > Then your business methods would look like this: > > database.inTransactionDo(new Runnable() { > public void run() { > <...business logic here...> > } > } > > Regards, > John Urberg > > > ------------------------------------------------------- > 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 > hib...@li... > https://lists.sourceforge.net/lists/listinfo/hibernate-devel |
From: Gavin K. <ga...@ap...> - 2002-11-16 14:12:41
|
Hmmm very cool. Hiram are there any ways in which Hibernate could support / integrate better with this framework? ----- Original Message ----- From: "Hiram Chirino" <hch...@jb...> To: "Urberg, John" <ju...@ve...>; "'Jozsa Kristof'" <dy...@on...> Cc: <hib...@li...> Sent: Saturday, November 16, 2002 3:49 PM Subject: RE: [Hibernate] Using hibernate - best practices > First time post... I like hibernate. I want to use it more with the Aspect > Framework that I'm build for JBoss. Anyways, here is a way a Jboss aspect > could help simplify things: > > You would use an interceptor that had an invoke method that looked something > like: > > class HibernateInterceptor { > ... > public Object invoke(AspectInvocation invocation) throws Throwable { > > HibernateContext oldHC = getHibernateContext(); > HibernateContext hc = null; > if( oldHC==null || oldHC.sessionFactory != sessionFactory ) { > hc = new HibernateContext(); > hc.sessionFactory = sessionFactory; > hc.session = sessionFactory.openSession(); > hc.transaction = hc.session.beginTransaction(); > setHibernateContext(hc); > } > > try { > > Object rc = invocation.invokeNext(); > > if( hc != null ) > hc.transaction.commit(); > > return rc; > > } catch ( Throwable e ) { > if( hc != null ) > hc.transaction.rollback(); > throw e; > } finally { > if( hc != null ) > hc.session.close(); > > setHibernateContext(oldHC); > } > } > .. > } > > class RuleListAction implemetns IRuleListAction { > .. > public String doDelete() throws Exception { > Session session= HibernateInterceptor.getSession(); > RuleList mo = (RuleList) session.load( RuleList.class, id ); > session.delete(mo); > return SUCCESS; > } > .. > } > > so that if you have DynamicProxy x with the HibernateInterceptor in the > invocation chain > then you could just do a: > > IRuleListAction x = (IRuleListAction )AspectFactory(new RuleListAction()); > x.doDelete() > > Regards, > Hiram > > > > > -----Original Message----- > > From: hib...@li... > > [mailto:hib...@li...]On Behalf Of Urberg, > > John > > Sent: Friday, November 15, 2002 8:30 AM > > To: 'Jozsa Kristof' > > Cc: hib...@li... > > Subject: RE: [Hibernate] Using hibernate - best practices > > > > > > >> The InvoiceRepository would be implemented like this: > > >> [code to load invoices] > > > > > 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? > > > > That's the responsibility of the database object. Code will usually look > > something like this: > > > > SomeRepository someRepository = database.getRepository(...); > > AnotherRepository anotherRepository = database.getRepository(...); > > database.startTrans(); > > try { > > someRepository.update(object); > > anotherRepository.update(object); > > database.commit(); > > } catch (Exception e) { > > database.rollback(); > > } > > > > All the code for dealing with sessions and transactions is safely tucked > > away in the database implementation. > > > > > These piece of codes are repeating in almost ALL of the Service classes' > > > business methods, are just flooding all the logic badly :( > > > > I'm not sure how you get around the whole transaction thing > > unless you're in > > a J2EE server that does that automatically. If you want to get rid of the > > boilerplate code, you could do something like this: > > > > public class Database { > > <...> > > public void inTransactionDo(Runnable doRun) { > > Session session = null; > > Transaction tx = null; > > try { > > session = Hibernator.getSession(); > > tx = session.beginTransaction(); > > doRun.run(); > > tx.commit(); > > } catch (Exception e) { > > logger.error (<blah/>), e); > > tx.rollback(); > > } finally { > > if (session != null) session.close(); > > } > > <...> > > } > > > > Then your business methods would look like this: > > > > database.inTransactionDo(new Runnable() { > > public void run() { > > <...business logic here...> > > } > > } > > > > Regards, > > John Urberg > > > > > > ------------------------------------------------------- > > 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 > > hib...@li... > > 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 > hib...@li... > https://lists.sourceforge.net/lists/listinfo/hibernate-devel |
From: Christoph S. <ch...@mc...> - 2002-11-18 15:38:11
|
take a look at nanning, it looks really nice too http://nanning.sf.net I'll make some experiments with it as soon as i find time, and try to ontegrate hibernate into it. peace chris ----- Original Message ----- From: "Gavin King" <ga...@ap...> To: <hib...@li...> Sent: Saturday, November 16, 2002 3:11 PM Subject: Re: [Hibernate] Using hibernate - best practices > Hmmm very cool. > > Hiram are there any ways in which Hibernate could support / integrate better > with this framework? > > ----- Original Message ----- > From: "Hiram Chirino" <hch...@jb...> > To: "Urberg, John" <ju...@ve...>; "'Jozsa Kristof'" > <dy...@on...> > Cc: <hib...@li...> > Sent: Saturday, November 16, 2002 3:49 PM > Subject: RE: [Hibernate] Using hibernate - best practices > > > > First time post... I like hibernate. I want to use it more with the > Aspect > > Framework that I'm build for JBoss. Anyways, here is a way a Jboss aspect > > could help simplify things: > > > > You would use an interceptor that had an invoke method that looked > something > > like: > > > > class HibernateInterceptor { > > ... > > public Object invoke(AspectInvocation invocation) throws Throwable { > > > > HibernateContext oldHC = getHibernateContext(); > > HibernateContext hc = null; > > if( oldHC==null || oldHC.sessionFactory != sessionFactory ) { > > hc = new HibernateContext(); > > hc.sessionFactory = sessionFactory; > > hc.session = sessionFactory.openSession(); > > hc.transaction = hc.session.beginTransaction(); > > setHibernateContext(hc); > > } > > > > try { > > > > Object rc = invocation.invokeNext(); > > > > if( hc != null ) > > hc.transaction.commit(); > > > > return rc; > > > > } catch ( Throwable e ) { > > if( hc != null ) > > hc.transaction.rollback(); > > throw e; > > } finally { > > if( hc != null ) > > hc.session.close(); > > > > setHibernateContext(oldHC); > > } > > } > > .. > > } > > > > class RuleListAction implemetns IRuleListAction { > > .. > > public String doDelete() throws Exception { > > Session session= HibernateInterceptor.getSession(); > > RuleList mo = (RuleList) session.load( RuleList.class, id ); > > session.delete(mo); > > return SUCCESS; > > } > > .. > > } > > > > so that if you have DynamicProxy x with the HibernateInterceptor in the > > invocation chain > > then you could just do a: > > > > IRuleListAction x = (IRuleListAction )AspectFactory(new RuleListAction()); > > x.doDelete() > > > > Regards, > > Hiram > > > > > > > > > -----Original Message----- > > > From: hib...@li... > > > [mailto:hib...@li...]On Behalf Of Urberg, > > > John > > > Sent: Friday, November 15, 2002 8:30 AM > > > To: 'Jozsa Kristof' > > > Cc: hib...@li... > > > Subject: RE: [Hibernate] Using hibernate - best practices > > > > > > > > > >> The InvoiceRepository would be implemented like this: > > > >> [code to load invoices] > > > > > > > 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? > > > > > > That's the responsibility of the database object. Code will usually > look > > > something like this: > > > > > > SomeRepository someRepository = database.getRepository(...); > > > AnotherRepository anotherRepository = database.getRepository(...); > > > database.startTrans(); > > > try { > > > someRepository.update(object); > > > anotherRepository.update(object); > > > database.commit(); > > > } catch (Exception e) { > > > database.rollback(); > > > } > > > > > > All the code for dealing with sessions and transactions is safely tucked > > > away in the database implementation. > > > > > > > These piece of codes are repeating in almost ALL of the Service > classes' > > > > business methods, are just flooding all the logic badly :( > > > > > > I'm not sure how you get around the whole transaction thing > > > unless you're in > > > a J2EE server that does that automatically. If you want to get rid of > the > > > boilerplate code, you could do something like this: > > > > > > public class Database { > > > <...> > > > public void inTransactionDo(Runnable doRun) { > > > Session session = null; > > > Transaction tx = null; > > > try { > > > session = Hibernator.getSession(); > > > tx = session.beginTransaction(); > > > doRun.run(); > > > tx.commit(); > > > } catch (Exception e) { > > > logger.error (<blah/>), e); > > > tx.rollback(); > > > } finally { > > > if (session != null) session.close(); > > > } > > > <...> > > > } > > > > > > Then your business methods would look like this: > > > > > > database.inTransactionDo(new Runnable() { > > > public void run() { > > > <...business logic here...> > > > } > > > } > > > > > > Regards, > > > John Urberg > > > > > > > > > ------------------------------------------------------- > > > 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 > > > hib...@li... > > > 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 > > hib...@li... > > 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 > hib...@li... > https://lists.sourceforge.net/lists/listinfo/hibernate-devel > |
From: Donnie H. <do...@ha...> - 2002-11-16 19:28:42
|
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: hib...@li... [mailto:hib...@li...]On Behalf Of Ampie Barnard Sent: Friday, November 15, 2002 2:22 AM To: hib...@li... 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: hib...@li... [mailto:hib...@li...]On Behalf Of Jozsa Kristof Sent: 15 November 2002 01:02 To: Urberg, John Cc: hib...@li... 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 hib...@li... 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 hib...@li... https://lists.sourceforge.net/lists/listinfo/hibernate-devel |
From: Jozsa K. <dy...@on...> - 2002-11-14 23:07:24
|
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 |