• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

EntityManager.flush not flushing

 
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I have created an EJB 3.0 application that consists of EJBs and JSP pages. I have a problem where a call to EntityManager.flush in a stateless session bean seems to be ignored. Here is what is happening:

A timer kicks off a stateless session been every X minutes. This bean does some work, sends an HTTP POST to another server and then logs an entry in an Oracle database that records that it sent the POST. This is done in a loop that could run 10 times, or hundreds of times. So every iteration of the loop makes an HTTP POST and creates 1 database record. After the end of each iteration I am calling flush to (try) and force the record to be written out to Oracle, and not just stored in JBoss� cache.

While the above loop is running, the server I sent the HTTP POST to in the loop above starts connecting to a JSP page I have created to say that it completed the work I sent it. The JSP page uses another stateless session bean, which looks up the database record created in the loop by its primary key and attempts to update it. The problem I am having occurs here. If the method with the loop above is still running, the database record is not found.

So JBoss is not storing the record in Oracle until the method completes, even though I am calling flush. And since my lookup for the record is based on its primary key, JBoss doesn�t check its cache but goes directly to the database (according to the docs I read anyway).

I am using JBoss 4.0.4. Does anyone have any tips or ideas as to how I can overcome this? Thanks!

DaHunter
 
Sheriff
Posts: 10445
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to JavaRanch

So JBoss is not storing the record in Oracle until the method completes, even though I am calling flush




As you mention that this is a method which is part of a bean, the data will not be comitted till the transaction completes (which happens to be when the method of the bean completes processing)
 
Mark Sohm
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks!

Can you think of any efficient way around this? Can I somehow tell the query in my second case to look in cache first, then the db?

I tried creating a second method in my timer bean that just logs the info, but it still isn't commited until the method with the loop ends.

I guess I could wrap the logic in my loop in its own bean. And have my timer create a new bean session each time in the loop, but that seems like it would have a stupid amount of overhead.

DaHunter
 
Jaikiran Pai
Sheriff
Posts: 10445
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

This is done in a loop that could run 10 times, or hundreds of times. So every iteration of the loop makes an HTTP POST and creates 1 database record.



See if this works right for your use case

- Create a method (lets call it createRecord) on the same bean.
- Let this method just create a record in the database
- Have the transaction attribute = RequiresNew for this method
- Call this method from the loop.

The createRecord method used create the record as part of a new transaction and commit the data as soon the createRecord method completes. It wont for the entire loop to complete processing.
 
Mark Sohm
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, but I tried this and it didn't make a difference. The records still aren't commited to Oracle until the main loop completes.

There has to be some way to tell JBoss to commit this data now... or tell it to pull data from its cache. This seems like a big hole that yeilds invalid data.

Any other ideas...? Is there a way I can tell JBoss to not cache any data for my application?

FYI, here is the method I created...


DaHunter
 
Jaikiran Pai
Sheriff
Posts: 10445
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am bit raw on the EntityManager. Let me see if can get hold of some document to brush up my knowledge on that and get back to you. And maybe, in the meantime, someone who knows more about this might lead you on the right track.
 
Mark Sohm
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, from all of the docs I've read it sounds like it is supposed to work this way. My next try is going to be changing this from a stateless session bean to a message bean. From what I've read, message beans don't have to occur in a transaction, unlike session beans. So I'm hoping I can force it to not occur within a transaction, which will let me flush the records. I'll let you know how it goes.

DaHunter
 
Mark Sohm
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The Message bean idea didn't work either... JBoss is still forcing my method to use a transaction, so I'm back to square 1. Actually, I'm 2 steps back now. After testing with larger data sets, meaning my loop runs longer, I'm getting commit timeouts writing to Oracle. So none of the data is being commited.

There has to be a way to tell EJB/JBoss to commit now, or else how does anyone handle a long running batch operation?

DaHunter
 
Jaikiran Pai
Sheriff
Posts: 10445
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"DaHunter"

Please check your private message, for a message from JavaRanch.
 
Mark Sohm
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I finally did get this to work how I wanted. I removed all references to EntityManager from my bean with the loop. I then set the method that creates the log entry to require a new trascation. This wrote out the database entry right away, but my loop still timed out writting to Oracle. To fix that problem I specified that the method that contains the loop does not support transaction, so JBoss doesn't try to do it all in a single transaction. Since I didn't have any reference to EntityManager anymore, JBoss was fine with that method not supporting transactions.

Mark
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic