GeeCON Prague 2014*
The moose likes JBoss/WildFly and the fly likes EntityManager.flush not flushing Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Products » JBoss/WildFly
Bookmark "EntityManager.flush not flushing" Watch "EntityManager.flush not flushing" New topic
Author

EntityManager.flush not flushing

Mark Sohm
Greenhorn

Joined: Jul 11, 2007
Posts: 19
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
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 10146
    
165

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)


[My Blog] [JavaRanch Journal]
Mark Sohm
Greenhorn

Joined: Jul 11, 2007
Posts: 19
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
Marshal

Joined: Jul 20, 2005
Posts: 10146
    
165

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

Joined: Jul 11, 2007
Posts: 19
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
Marshal

Joined: Jul 20, 2005
Posts: 10146
    
165

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

Joined: Jul 11, 2007
Posts: 19
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

Joined: Jul 11, 2007
Posts: 19
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
Marshal

Joined: Jul 20, 2005
Posts: 10146
    
165

"DaHunter"

Please check your private message, for a message from JavaRanch.
Mark Sohm
Greenhorn

Joined: Jul 11, 2007
Posts: 19
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
 
 
subject: EntityManager.flush not flushing