views:

149

answers:

3

I have a small system consisting of a .net client and a java web service.

The .net client inserts an object into the database, and then calls the web service. The web service tries to retrieve this object using hibernate. First time it works fine, but every other time it says that there is no object with the given identifier.

I have checked the database manually and the row is indeed there! (I debugged the web service and checked for the row even before a session was opened).

SOLUTION

Added this to the hibernate config file

<property name="connection.isolation">1</property>

Here's what I've tried so far:

  1. The second level cache is disabled
  2. Added .setCacheMode(CacheMode.REFRESH)

Here's the failing code:

Session session = Program.HibernateUtil.getSessionFactory().openSession();   
try    
{
    return (Alert)session.load(Alert.class, id);                     
} ...
A: 

Try setting this hibernate property:

hibernate.cache.provider_class = org.hibernate.cache.NoCacheProvider

Peter Thomas
Hi. I already have this in my config.!-- Disable the second-level cache --><property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
l3dx
+2  A: 

It looks like the second level cache (the one associated with the session factory) should be disabled so the only other thing I can suggest is to explicitly clear the cache with the call:

sessionFactory.evict(Alert.class)

Note: read the comments for the full answer.

Nick Holt
Thanks. I tried, but it didn't make any difference.
l3dx
Now that's odd. How are your connections being managed? Could there be some weird isolation level/transaction problem where the connection genuinely can't see the updates made by the other process?
Nick Holt
I'm not sure if you by connection mean the session? If so, I'm using the HibernateUtil helper class provided in the Hibernate tutorial http://docs.jboss.org/hibernate/stable/core/reference/en/html/tutorial.html#tutorial-firstapp-helpers
l3dx
No, I mean the underlying database connection that Hibernate is using. Please can you post you hibernate.cfg.xml file, which is where the database connection if configured.
Nick Holt
I've added it to the question :-)
l3dx
Ta - so first of all (and I know this might sound stupid) are you sure you're pointing at the same database? I notice Hibernate is configured to update the DB at start-up and so even if you're pointing at the wrong database the schema will be there. Once you've confirmed that try setting connection.isolation to 1 (TRANSACTION_READ_UNCOMMITTED) - if you can then see the data then you've got a problem with an uncommitted transaction in your C# code. After that, I'm starting to scratch my head as to what code be wrong.
Nick Holt
connection.isolation = 1 seems to do the trick! Thanks a lot :)
l3dx
Cool - be careful with that though, it basically means you're performing dirty reads (reading data that's been updated within a transaction that hasn't been committed). Without knowing your system this could be a timing issue but if you've got a transaction hanging open that's bad and will cause problems down the line.
Nick Holt
I still don't understand how the row cannot be committed when I have transaction.Commit(); in the client code, and can see the row in the database, but it still counts as not committed. I believed that hibernate didn't pass anything to the database before .commit() was invoked.
l3dx
Without seeing more of the code base it's hard to tell, but as switching the isolation level of the database connection in the Java process to TRANSACTION_READ_UNCOMMITTED has made the data visible, it certainly seems that something is up transaction-wise with the process writing the data.
Nick Holt
+1  A: 

Firstly, don't use Session.load(), use Session.get(). load() should only be used in very particular situations, and this ain't one of them.

Secondly, are you performing both operations within the same Session? If so, Hibernate will cache the entity after the first operation. There's no way to stop it doing this. However, you can use evict() on the Session to forceably kick the entity out of the session cache.

skaffman
1) I actually first tried using createQuery(), but I will try using get(). I'll also read up on what the difference between get/load ;) 2) If you by "both operations" mean insert/select, they're even on different machines. The client using NHibernate(.net), and the web service using Hibernate(java). Tried the evict approach as also suggested by Nick Holt :)
l3dx