-->
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.  [ 2 posts ] 
Author Message
 Post subject: Why does flush() after a query cause a DB update?
PostPosted: Fri Sep 26, 2014 12:23 pm 
Newbie

Joined: Fri Sep 26, 2014 11:44 am
Posts: 2
I inherited an application that uses Hibernate which I had never used before. The 'standard' coding practice in this app (these guys were horrible programmers in many ways) was to create a session for every query/update, perform the query/update, then flush() and close() the session. Until now I didn't have an issue with this, but now I am. The situation is this:

1. Query the DB for a UserObject as they log in
2. Save the UserObject into web storage for the users webapp session
3. Use values in the UserObject to modify look/behavior of screens

#2 is the new piece - previous code had saved some individual UserObject values or queried the DB every time in every action after the user clicked something. But now that I'm storing/saving the UserObject in memory, other queries on this table/object cause the DB to hang on an update failure which Hibernate is performing during flush() after the query. Why is Hibernate performing a DB update when the object was simply queried?

I know I'm an old school programmer, where DB transactions were small ( open, read/write, commit/close ) and never had user interaction inside because this would escalate row, table, and tablespace locks. So maybe I'm not understanding how Hibernate persistence works and how it should be coded. Should flush() never be used after a query? Should there be only one 'session' object for each users webapp 'session'? Is Hibernate persistence supposed to eliminate having to actually code an 'update' because it'll happen automatically under the covers? Meaning the model is to query hibernate/db/Java objects, have the user modify fields, have code that updates the Java objects and then one flush() + commit() updates everything in the DB?


Top
 Profile  
 
 Post subject: Re: Why does flush() after a query cause a DB update?
PostPosted: Fri Oct 03, 2014 5:13 pm 
Newbie

Joined: Thu Aug 14, 2014 5:13 pm
Posts: 3
Although not the only or easiest way to do things, hibernate works very well in a transaction isolated situation like transaction managed EJB's.
The example below is a simple way to perform the operation with EJB 3 and an application server
(http://docs.oracle.com/javaee/5/tutorial/doc/bncij.html for detailed explaination)


Code:
@Stateless
public class MyStuffService {
   @PersistenceContext
   EntityManager entityManager;
   
   /* This line isn't strictly needed unless you're also modifying the contents of myQueriedStuff */
   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public Stuff getMyStuff() {
      /* Do your DB queries in here */   
      return myQueriedStuff;
   }
   
   /* REQUIRES_NEW not strictly necessary */
   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public void saveMyCurrentStuff(Stuff myCurrentStuff) {
      entityManager.merge(myCurrentStuff);
      /* .flush() not necessary because entityManager will be flushed automatically by the container manged transaction scaffolding in the application server */
   }
}

class MyWebTier {
   
   /* The application server will automatically create or use an instance of MyStuffService to service the calls using JNDI and/or CDI, but all you should care about is that you have an instance */
   @EJB
   MyStuffService service;

   public void save(Stuff stuff) {
      service.save(stuff);
   }

   public Stuff getLatestStuff() {
      return service.getMyStuff();
   }
}



In this way, when you leave the method (and your application server is setup correctly) your service will return a 'detached' copy of the query results. The detached part is important. If you modify 'myQueriedStuff' while it is still attached to hibernate, a .flush() call to hibernate will take all outstanding changes to the code and save them back to the DB.

I've always worked in transaction blocks with EJB's because its safer and more predictable. I'm not sure if you're using an appserver/stand-alone/or just servlet container, but depending on your environment, it can be a lot simpler to enforce certain behaviours. EJB is great because it gives you a nice simple isolation boundary between things happening in the backend/DB vs. the front end web tiers, which should ideally not know or care about the 'heavy lifting' being done in its stead.


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