-->
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.  [ 6 posts ] 
Author Message
 Post subject: EntityManager's flush() not writing changes to database
PostPosted: Thu Apr 21, 2011 9:49 am 
Newbie

Joined: Thu Apr 21, 2011 8:59 am
Posts: 14
Hi,
I am using jboss(version-4.3.0.GA) with hibernate(hibernate.version>3.2.5.ga, hibernate.entitymanager.version>3.3.2.GA).
I have written a small stateless bean to test a scenario with entitymanager and found that flush is not actually writing changes to the database till the transaction commits.

==pseudo code==
Code:
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class TestClass {

@PersistenceContext()
private EntityManager em;

public testFunc(){
1. fetch an existing entity from database using em.find()
2. modify the entity, merge the changes using em.merge() and invoke em.flush()
3. sleep for a minute using Thread.sleep() to verify the database
}


Now, when I invoke the testFunc() and look at the database during the sleep in step 3, I see that the changes made to the entity in step 2 are not actually yet written to the database. However, they get saved to the db only when transaction commit happens( after the call to testFunc ends). Is this the expected behaviour?

The hibernate EntityManger's document says
Quote:
Flush occurs by default (this is Hibernate specific and not defined by the specification) at the following points:
* before query execution*
* from javax.persistence.EntityTransaction.commit()*
* when EntityManager.flush() is called*


Going by the documentation, since flush() is called in step2, the changes should have actually got written to the database but that is not happening. Hibernate seems to write changes only as part of the auto-flush which happens at transaction commit time but not when flush() is called explicitly. Is this an issue with this version of hibernate ?

I tried using hibernate's FlushMode.MANUAL but the result still is the same.
Code:
public testFunc(){
org.hibernate.Session session = (Session) em.getDelegate();
session.setFlushMode(org.hibernate.FlushMode.MANUAL);
System.out.println("from em.getDelegate session flushmode="+session.getFlushMode()); //printing FlushMode.MANUAL
System.out.println("em flushmode="+em.getFlushMode()); // printing null
1. fetch an existing entity from database using em.find()
2. modify the entity, merge the changes using em.merge() and invoke em.flush()
3. sleep for a minute using Thread.sleep() to verify the database
}

Even with this manual flushmode, I see that the changes in step2 are not written to database by the flush() call. They are only getting reflected after the transaction commit.

Any suggestions or details on how to make em.flush() write changes to the database would be helpful.

Thanks,
Lokesh.

_________________
Lokesh, C
( SCBCD 5, CCENT, SCJP 5 )


Top
 Profile  
 
 Post subject: Re: EntityManager's flush() not writing changes to database
PostPosted: Thu Apr 21, 2011 10:02 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
Now, when I invoke the testFunc() and look at the database during the sleep in step 3, I see that the changes made to the entity in step 2 are not actually yet written to the database.


How do you check this? If your transaction in Hibernate hasn't been committed it is not surprising if you can't see the changes from an external tool. It all comes down to which transaction isolation level you have specified in the tool you are using to check the database. You should check for an option like READ_UNCOMMITTED or similar.


Top
 Profile  
 
 Post subject: Re: EntityManager's flush() not writing changes to database
PostPosted: Tue Apr 26, 2011 2:19 am 
Newbie

Joined: Thu Apr 21, 2011 8:59 am
Posts: 14
Hi nordborg,
Thanks for the response.
I am working on postgreSQL database and using pgAdmin III to verify the content in the database. The transaction-isolation specified in our datasource is TRANSACTION_READ_COMMITTED.
However, I still have a question on why the changes are not written to the database in step 2.

I see that "JSR 220: Enterprise JavaBeansTM,Version 3.0" says the following on em.flush
Quote:
/**
* Synchronize the persistence context to the
* underlying database.
* @throws TransactionRequiredException if there is
* no transaction
* @throws PersistenceException if the flush fails
*/
public void flush();

and

The persistence provider runtime is permitted to perform synchronization to the database at other times
as well when a transaction is active. The flush method can be used by the application to force synchronization.
It applies to entities associated with the persistence context.


So, in both scenario1( when i used default flushMode of AUTO for the persistence context ) and scenario 2( where i have set the flushMode to MANUAL ), since em.flush is invoked by the application, the changes in the persistence context should have been written to the database.
Is that correct or am I missing something?

Is it that hibernate writes changes to the database only at the transaction commit time( at the end of testFunc) irrespective of whether em.flush is invoked by the application or not?

Thanks,
Lokesh.

_________________
Lokesh, C
( SCBCD 5, CCENT, SCJP 5 )


Top
 Profile  
 
 Post subject: Re: EntityManager's flush() not writing changes to database
PostPosted: Tue Apr 26, 2011 3:02 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
The changes are written to the database when flush is called. But the transaction isolation setting (READ_COMMITTED) prevents you from seeing the changes from outside until the transaction have been committed. And as far as I know PostgreSQL doesn't support READ_UNCOMMITTED so it will not help to change to that level either. See http://www.postgresql.org/docs/9.0/stat ... n-iso.html for a good description about this.

The changes will be visible from within the same transaction, so you can easily test this if you instead of step 3 in your test code make a query (HQL or SQL) against the database.


Top
 Profile  
 
 Post subject: Re: EntityManager's flush() not writing changes to database
PostPosted: Wed Apr 27, 2011 3:12 am 
Newbie

Joined: Thu Apr 21, 2011 8:59 am
Posts: 14
Hi nordborg,

Thanks for the clarification. I would verify the suggested step of direct SQL on the database to verify the functionality of flush. Can you provide some details on the following additional questions that I have as well.

1. So, when a transaction isolation setting (READ_COMMITTED) is used and if there are two parallel transactions running(tx1, tx2), changes made in tx1 would be visible to tx2 only after tx1 commits. Is this true irrespective of what flushmode(AUTO or COMMIT) is used in tx1 or not?
Is this true irrespective of whether em.flush is explicitly called in tx1 or not?

2. When a flushmode of AUTO is being used in a tx and the tx isolation is READ_COMMITTED, why do we need to need em.flush explicity? The changes would anyways be flushed and committed at the end of tx.

Thanks,
Lokesh.

_________________
Lokesh, C
( SCBCD 5, CCENT, SCJP 5 )


Top
 Profile  
 
 Post subject: Re: EntityManager's flush() not writing changes to database
PostPosted: Wed Apr 27, 2011 3:25 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
1. Yes that is correct.

2. You do not need to explicitly call flush() when using the AUTO flush mode. The AUTO flush mode has certain rules to determine when a flush should happen. It may happen multiple times during a session/transaction as well as when commit is called. See http://docs.jboss.org/hibernate/core/3. ... e-flushing for more information about flush modes.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.