-->
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.  [ 8 posts ] 
Author Message
 Post subject: Transactions and Atomicity
PostPosted: Thu May 20, 2010 9:26 am 
Newbie

Joined: Tue Mar 24, 2009 1:09 pm
Posts: 14
Hi,

Im having an odd probelm while running my Junits (Im running them within eclispe with JUnit4, Spring 3 and hibernate 2.3).

I think the problem is tied up with the fact Im running my tests within a transaction, setting up database test data first within the test transaction, then using that test data in my tests.

So, within a single transaction I basically do the following:
create a new entity
retrieve the entity
update entity (uses HQL UPDATE User where usercode=:code)
retrieve entity <--- entity not found

create a new entity
retrieve the entity
update entity (uses EntityManager.merge())
retrieve entity <--- entity found and Update was retieved

Why does my update vai HQL subsequently create a dirty read later on where as if I do an update using EntityManager.persist or EntityManager.merge ?

I added a flush after the update but that didnt make any difference to the retreive.

Thanks

Tim


Top
 Profile  
 
 Post subject: Re: Transactions and Atomicity
PostPosted: Thu May 20, 2010 9:59 am 
Newbie

Joined: Tue Mar 24, 2009 1:09 pm
Posts: 14
ok,

The retreival that failed wasnt finding the updated entity at all, and I found out that a pointcut had been modified which now included an aspect that set up a hibernate filter that stopped me seeing the updated entity, due to the very update I was making!

Anyway, now I fixed that, I still have an issue with atomicity of the transaction in that the last retrieve of the updated value still fails to get an updated entity unless I use entitManager.merge(). If I use a straight HQL with something like "UPDATE User set column=:foo, the subsequent retrieval fails to see the updated value.

create a new entity
retrieve the entity
update entity (uses HQL UPDATE User where usercode=:code)
retrieve entity <--- entity found but updated value was missing

create a new entity
retrieve the entity
update entity (uses EntityManager.merge())
retrieve entity <--- entity found and Update was retieved


Im aware that hibernates first level cache only works on selection of entities by id so from JPA point of view only entityManager.find(id) is going to hit the cache. However, surely if Im working within a transaction and flushing after an update I should see my updated values if I reretrieve an entity within the same transaction as the update?


Top
 Profile  
 
 Post subject: Re: Transactions and Atomicity
PostPosted: Thu May 20, 2010 2:52 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
This is a quote from the Hibernate documentation at http://docs.jboss.org/hibernate/stable/ ... tch-direct

Quote:
This means that manipulating data directly in the database (using the SQL Data Manipulation Language (DML) the statements: INSERT, UPDATE, DELETE) will not affect in-memory state.


So once you start using DML in a transaction the entities in the session cache will no longer match what is in the database. The two examples in your post is the expected behavior. If you, in the first example, want to retrieve the entity with updated values, you can for example call Session.refresh(). I don't know if this method (or an equivalent) exists in EntityManager.


Top
 Profile  
 
 Post subject: Re: Transactions and Atomicity
PostPosted: Fri May 21, 2010 3:01 am 
Newbie

Joined: Tue Mar 24, 2009 1:09 pm
Posts: 14
nordborg wrote:
This is a quote from the Hibernate documentation at http://docs.jboss.org/hibernate/stable/ ... tch-direct

Quote:
This means that manipulating data directly in the database (using the SQL Data Manipulation Language (DML) the statements: INSERT, UPDATE, DELETE) will not affect in-memory state.


So once you start using DML in a transaction the entities in the session cache will no longer match what is in the database. The two examples in your post is the expected behavior. If you, in the first example, want to retrieve the entity with updated values, you can for example call Session.refresh(). I don't know if this method (or an equivalent) exists in EntityManager.


Hi, thanks for answering.

The reason I did an update is that in the particular bit of code I only have the entities id (surrogate key) or code (natural key) - its a soft delete so Im doing "softDeleteById()" which updates an isActive flag for the tuple.

Now, Im actually doing an HQL update, or atleast I guess a JPA update?. I use the entity name rather than the table name. Im NOT using the hibernate session to create the query, only the EntityManager, but Id be surprised if this was the issue. The link you gave goes on to say that using HQL/JP-QL will keep the cache upto date.

Below the commented out stuff is what didnt work (or rather it performed the update but didnt all a subsequent read in the same transaction to read the updated value), and is replace with the entityManager.find followed by an entityManager.merge.

EntityManager entityManager = BaseEntity.entityManager();

// StringBuffer queryBuff = new StringBuffer("UPDATE ");
// queryBuff.append(entityType.trim());
// queryBuff.append(" SET isActive=").append(INACTIVE_STATE);
// queryBuff.append(" WHERE code = :codeparam");
// Query q = entityManager.createQuery(queryBuff.toString());
// q.setParameter("codeparam", entityCode);


BaseEntity entity = findEntityByCode(entityCode, entityType);

try
{

entity.setIsActive(INACTIVE_STATE);
entity.merge();
// q.executeUpdate();
// entityManager.flush();

}

The only thing I can think of is the update is running in a different transaction - or nested transaction, but Im using @Transactional(propagation = Propagation.REQUIRED) throughout (on both service methods and DAO methods for safety - but REQUIRED should propergate the current transaction)


Top
 Profile  
 
 Post subject: Re: Transactions and Atomicity
PostPosted: Fri May 21, 2010 3:19 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
The link you gave goes on to say that using HQL will keep the cache upto date.


Where does it say that?

Quote:
Im NOT using the hibernate session to create the query, only the EntityManager


An EntityManager is more or less just a wrapper around a Hibernate Session with some stuff thrown in to make it behave as JPA specs require. Under the hood you are using a Hibernate session. The Hibernate session has an internal cache of entities that it is managing. UPDATE queries go directly to the database and will not affect the information that is already in the cache.


Top
 Profile  
 
 Post subject: Re: Transactions and Atomicity
PostPosted: Fri May 21, 2010 3:42 am 
Newbie

Joined: Tue Mar 24, 2009 1:09 pm
Posts: 14
nordborg wrote:
Quote:
The link you gave goes on to say that using HQL will keep the cache upto date.


Where does it say that?

Hi

I guess it doesnt say it explicitly, but to me it implies that HQL will maintain its in memory representation.

http://docs.jboss.org/hibernate/stable/ ... tch-direct

Quote:
As already discussed, automatic and transparent object/relational mapping is concerned with the management of object state. This implies that the object state is available in memory, hence updating or deleting (using SQL UPDATE and DELETE) data directly in the database will not affect in-memory state. However, Hibernate provides methods for bulk SQL-style UPDATE and DELETE statement execution which are performed through JP-QL (Chapter 8, JP-QL: The Object Query Language).


Having said that, it doesnt appear to be doing it. I can underastand using SQL would not keep the in-memory entities upto date because that would imply parsing the SQL to find entities that are mapped and update the in memory entity accordingly - a whole nother ball game. But for HQL, hibernate has to parse this anyway and Id be very surprised if it didnt maintain its first level cache based on these updates.

However, I've been using hibernate for what, 5 years or so, and never had an issue like this before that I can remember, and I've used plenty of HQL in the past. Perhaps I just never had to do an update that I need to see later on in same transaction.

hmmmm


Top
 Profile  
 
 Post subject: Re: Transactions and Atomicity
PostPosted: Fri May 21, 2010 4:04 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
1. Hibernate is an ORM tool which is about managing object state in memory.

2. But Hibernate does also provide bulk-update/delete statements.

3. Such statements will not affect in-memory state.


Top
 Profile  
 
 Post subject: Re: Transactions and Atomicity
PostPosted: Fri May 21, 2010 4:18 am 
Newbie

Joined: Tue Mar 24, 2009 1:09 pm
Posts: 14
nordborg wrote:
1. Hibernate is an ORM tool which is about managing object state in memory.

2. But Hibernate does also provide bulk-update/delete statements.

3. Such statements will not affect in-memory state.


ok, fair enough. (I dont think its very well written though - i.e "You can do SQL but in memory state not updated... However .... ). I guess since its possible to update multiple rows in a single statement it wouldnt be easy for hibernate to figure out whats getting updated without going validating the "where" conditional and of course not all entities that maybe affected would be in the in memory representation either. Actually, the more I think about it the more obvious it is.

I guess I could clear the first level cache which would cause the subsequent read to query the database which should return the updated entity eeven though we didnt commit yet (assuming its all done in the same transaction)

I didnt want to do a read followed by an update thinking it was less efficent. But I guess the read before the update will only have to retrieve the entity from the cache so no real hit there anyway.

interesting. Thanks for your help.


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