And George, read this one: http://stackoverflow.com/questions/10143880/hibernate-queries-much-slower-with-flushmode-auto-until-clear-is-called. It explains why you experience the slow downs and what is it causing it.
2013/10/25 Martin Kersten <martin.kersten...@gmail.com> > You might also want to use such kind of a utility that allows you to run > in transaction: > > public interface InTransaction<T> { > public T run(Session session); > } > > public static <T> T DatabaseUtil.process(InTransaction<T> > transactionalRunnable) { > try { > Session session = currentSession(); //or newSession() > if(!session.getTransaction().isActive()) > session.beginTransaction(); > T result = transactionalRunnable.run(session); > if(!session.getTransaction.isActive()) { > session.getTransaction().commit(); > session.clear(); > } > } > catch(RuntimeException e) { > if(session.getTransaction().isActive()) { > session.getTransaction().rollback(); > session.clear(), > } > } > finally { > //session.close(); //if you created a new one > } > } > > > This way you can control the whole transactional process while only doing: > > List<Product> product = DatabaseUtil.process(new > InTransaction<List<Product>>() { > List<Product> run(Session session) { > //getUser etc are all static methods fetching from a > ThreadLocal RequestContext object so you dont need > //to inject / pass along parts of your model in every > component/page > UserInfo user = getUser(); > userStats.countUserRequest(user); //changes the database; > return queryProductsForUser(user, session); //returning a list > } > } > > This example is just made up to demonstrate that you can return a > List<Product> or Integer or if you have nothing to return > a Void instance. > > The DatabaseUtil class I use for everything that happends outside of a > request therefore when I have to control the sessions > being opened, closed and manage the transaction. This way you even not run > into any difficult with nesting (you can not > leave the transaction (since it is an enclosed try catch block), > > I have set my session to automatically clear the persistence context on > commit. > You can do this by ((SessionImpl)session).setAutoClear(true). > > And of cause checking if a transaction is active can be extracted to a > private method to value the DRY principle. > > > > > 2013/10/25 Martin Kersten <martin.kersten...@gmail.com> > >> > session.flush(); >> > session.clear(); >> > hibernateSessionManager.commit(); >> >> This is wrong. >> First on commit you will do the flush automatically (flush means all >> changes are written to the database (performing outstanding updates, >> inserts, deletes)) >> Clear clears the persistence context of all entities not taking part on >> any outstanding flush event (as far as I remember) therefore Hibernate does >> a deep >> inspection of the active entities and removes all entities that were not >> encountered during that process. >> Commit commits the entities. >> >> So the correct usage is: >> session.getTransaction().commit(); >> session.clear(); >> session.beginTransaction(); >> >> (without the clear its what HibernateSessionManager is doing with the >> session bound to the current thread). >> >> >> >> >> 2013/10/25 Martin Kersten <martin.kersten...@gmail.com> >> >>> Use: >>> >>> @Inject >>> Session session; //current session bound to the current thread >>> >>> >>> or >>> >>> @Inject >>> HibernateSessionSource source; + source.create() for a really new >>> session (CommitAfter would not work with newly created one); >>> >>> Using the Manager does give you only the session associated with the >>> current thread as would @Inject Session session; would do. >>> >>> >>> >>> >>> 2013/10/25 George Christman <gchrist...@cardaddy.com> >>> >>>> So I guess I'm still a little confused as to what is the best to do it. >>>> @CommitAfter seems to work fine for individual transactions but does not >>>> work well with batch jobs do to it holding on to the object in memory. >>>> Anyhow, I could not figure out how to get Martins >>>> session.getTransaction() >>>> to work, however I did end up getting the following code to work. Could >>>> someone tell me if I'm doing this correctly? Also should I be closing >>>> and >>>> rolling back the transaction? >>>> >>>> //Mock scenario >>>> >>>> @Inject >>>> private HibernateSessionManager hibernateSessionManager; >>>> >>>> public void onActionFromTest() { >>>> Session session = hibernateSessionManager.getSession(); >>>> >>>> for (int i = 0; i < 100000; i++) { >>>> employee = new Employee("George " + i); >>>> >>>> session.save(employee); >>>> >>>> if (i % 250 == 0) { >>>> session.flush(); >>>> session.clear(); >>>> hibernateSessionManager.commit(); >>>> } >>>> } >>>> >>>> session.flush(); >>>> session.clear(); >>>> hibernateSessionManager.commit(); >>>> >>>> >>>> >>>> On Fri, Oct 25, 2013 at 9:07 AM, Thiago H. de Paula Figueiredo < >>>> thiag...@gmail.com> wrote: >>>> >>>> > On Fri, Oct 25, 2013 at 10:53 AM, Barry Books <trs...@gmail.com> >>>> wrote: >>>> > >>>> > While it's true you can run into problems by nesting @CommitAfter the >>>> same >>>> > > can be said about nesting any commits. The Tapestry database model >>>> is >>>> > > simple. There is one connection per request and when you call >>>> commit it >>>> > > does a commit. >>>> > > >>>> > >>>> > <pedantic> >>>> > Tapestry itself doesn't have any database model. It's a web framework >>>> and >>>> > nothing else. You can use it with any database, including none. >>>> > Tapestry-Hibernate is a package that provides *simple* support for >>>> > Hibernate and should be used in *simple* scenarios. If you need >>>> something >>>> > that's not simple, like any transaction handling not supported by >>>> > @CommitAfter, use Tapestry and some transaction handler (EJB, >>>> Spring-TX, >>>> > etc) but not Tapestry-Hibernate. >>>> > </pedantic> >>>> > >>>> > >>>> > >>>> > > >>>> > > >>>> > > On Fri, Oct 25, 2013 at 7:31 AM, Lance Java < >>>> lance.j...@googlemail.com >>>> > > >wrote: >>>> > > >>>> > > > I'm assuming a fork is broken too because it's no good for eating >>>> soup? >>>> > > > Sounds like you need a spoon, it's easy to write your own >>>> annotation... >>>> > > > Perhaps you want a @MaybeCommitAfter ;) >>>> > > > >>>> > > >>>> > >>>> > >>>> > >>>> > -- >>>> > Thiago >>>> > >>>> >>>> >>>> >>>> -- >>>> George Christman >>>> www.CarDaddy.com >>>> P.O. Box 735 >>>> Johnstown, New York >>>> >>> >>> >> >