aspose file tools*
The moose likes Object Relational Mapping and the fly likes Problem with Hibernate Cache Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Problem with Hibernate Cache" Watch "Problem with Hibernate Cache" New topic
Author

Problem with Hibernate Cache

Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Hi All,

I have a problem related to hibernate. I have a single database which is being shared by two applications( PHP and Flex ). PHP applications when updates the data in database. Flex application through webservice get this latest data and display accordingly.

The problem here i am facing is because of hibernate cache. my PHP application updates the DB, but webservice returns the old data to flex client.

if i create sessionFactory multiple times, it's not a good solution as it will increase load on my application, so i want to keep it static and want to instantiate only once.

How to let my application to get latest data?

Thanks


Lack of will power has caused more failure than lack of intelligence or ability.
My Blog | Red5 Resources | Technology Update | Daily Technology Tips
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336


if i create sessionFactory multiple times, it's not a good solution as it will increase load on my application, so i want to keep it static and want to instantiate only once.

You don't need a new SessionFactory, just open a new Session. Sessions are cheap to create.


JavaRanch FAQ HowToAskQuestionsOnJavaRanch
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Originally posted by Paul Sturrock:

You don't need a new SessionFactory, just open a new Session. Sessions are cheap to create.


I think, you did not get my problem, I can create session and later i can close them. That's not an issue. Even after destroying the session, Everytime i get the old data. External application is updating the database and i am not able to get this latest data.

Hope i am clear now. Thanks for replying
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Opening a new session gets the latest data from the database (unless you are using a second level cache?), so perhaps I don't unerstand the flow of your application? Assuming your PHP app. updates the database, then your Hibernate backed app. opens a session (or flushes an existing open session) and uses that to read from the database it will return the latest data.

If you are using a second level cache you may want ot change your CacheMode, or decide whether you really need a second level cache for these objects?
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Hi Paul,

I have not used second level cache and by default the second level cache is disabled. This is my .cfg file


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated file - Do not edit! -->

<hibernate-configuration>

<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory>

<!-- properties -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="use_outer_join">true</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/_playlistdb</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>


<!-- mapping files -->
<mapping resource="com/xxx/entity/playlistdb/PlaylistLogHourlyBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistWordBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistClipDataBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistRoleBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistCommentBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistLogDetailBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistRatingBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistBaseDataBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistItemParameterBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistLogDailyBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistAccountParameterBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistTrackbackBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistTagBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistBaseParameterBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistPlayLogBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistItemDataBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistReferenceBean.hbm.xml"/>
<mapping resource="com/xxx/entity/playlistdb/PlaylistClipParameterBean.hbm.xml"/>
</session-factory>

</hibernate-configuration>


and in my implementation-

session = getSessionFactory().openSession();

After my transactions-

} finally {
session.close();
}
in finally block, i am closing the session.

But I am getting the old data only
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

When does your PHP app update the data? After you open the session?

The method you call will create a new connection to the database and read from it. So this will not return old data, it will return data from the current state of the database.

How are you ascertaining that your data is old?
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Originally posted by Paul Sturrock:
When does your PHP app update the data? After you open the session?

The method you call will create a new connection to the database and read from it. So this will not return old data, it will return data from the current state of the database.

How are you ascertaining that your data is old?


Very simple scenario-

My flex application called a web service and got the current data from DB, now i go to MySQL and manually change any field and say my flex client to call web service again and flex client gets the old data as long as i don't start tomcat again.

Whatever changes i make in DB manually, does not reflect to my flex client.
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

The SQL Client you are using, does it auto commit? Or do you need to manually commit data after you make a change?
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Originally posted by Paul Sturrock:
The SQL Client you are using, does it auto commit? Or do you need to manually commit data after you make a change?


I am using MySQL Control Center. I tried to run commit command also after making changes but no luck.
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Well, if you are using Hibernate as you say you are then it is not Hibernate that is caching the data. SessionFacotry.openSession() gets a new connection from the pool. When you call get or load on that session the data is read from the database. I'd examine what your Flex app. is up to. Does it cache anythign itself?
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Originally posted by Paul Sturrock:
Well, if you are using Hibernate as you say you are then it is not Hibernate that is caching the data. SessionFacotry.openSession() gets a new connection from the pool. When you call get or load on that session the data is read from the database. I'd examine what your Flex app. is up to. Does it cache anythign itself?


No, the problem is not on flex end. As i discussed earlier, if i create a new session factory each time when my flex client call the webservice. then i get the updated data as soon as i update data in DB( manually or through PHP). Flex client is just calling the Axis webservice which actually does all hibernate transactions. No cache implementation on Flex side.
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
My code of getting data is -

Criteria crit = session.createCriteria(PlaylistBaseDataBean.class);
crit.add(Expression.eq("id", playlist.getId()));
List<PlaylistBaseDataBean> list = crit.list();


PlaylistBaseDataBean playlistBaseDataBean = (PlaylistBaseDataBean)list.get(0);

PlaylistBaseDataBean maps to a table in database.
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Well, Hibernate is not caching anything in the scenario you suggest. Can you show us your Hibernate code?
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Do you use a query cache?
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Originally posted by Paul Sturrock:
Do you use a query cache?


No, I don't as you can see also in my file

<property name="hibernate.cache.use_query_cache">false</property>

I did everything to fix this issue. But
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Well I'm kind of struggling to think of other things to suggest. I know that opening a new session guarentees the latest data is being read from the database, so you can be certain that it is not Hibernate itself caching the data. Something else must be doing it.

What sort of updates do you make that are not being reflected? inserts? or updates to an existing record?

[ June 26, 2008: Message edited by: Paul Sturrock ]
[ June 26, 2008: Message edited by: Paul Sturrock ]
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
I am just updating the value of any field in database. Say title changed from Hello to Hello123. I am pasting my code and log here.





and my log says, when client hit the webservice-

Automatic flush during beforeCompletion(): disabled
- Automatic session close at end of transaction: disabled
- Cache provider: org.hibernate.cache.EhCacheProvider
- Second-level cache: disabled
- Optimize cache for minimal puts: disabled
- Structured second-level cache entries: disabled
- Query cache: disabled
- Echoing all SQL to stdout
- Statistics: disabled
- Deleted entity synthetic identifier rollback: disabled

Gettting old data only. Till i restart the tomcat server or creates multiple SessionFacrories. This is strange, also According to documentation of Hibernate, Second level cache is disabled by default. But if i don't add the below line
<property name="hibernate.cache.use_second_level_cache">false</property>

I can see in my log

- Second-level cache: enabled

It means it is enabling second level cache by default.

[ edited to use code tags - Paul Sturrock ]
[ June 26, 2008: Message edited by: Paul Sturrock ]
g wildin
Greenhorn

Joined: Jun 26, 2008
Posts: 3
Allow me to guess (disclaimer: I just took a hibernate class, but have no experience with it...). Maybe you are getting the detached object - that is why it is the old data. I think you can use if(session.contains(obj)) { session.evict(obj); } to remove it. Hope this helps.
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Originally posted by g wildin:
Allow me to guess (disclaimer: I just took a hibernate class, but have no experience with it...). Maybe you are getting the detached object - that is why it is the old data. I think you can use if(session.contains(obj)) { session.evict(obj); } to remove it. Hope this helps.


This evict function will go where in my code given below.

try{ session = getSessionFactory().openSession(); System.out.println("PlayList: Session created"); Criteria crit = session.createCriteria(PlaylistBaseDataBean.class);crit.add(Expression.eq("id", id));List<PlaylistBaseDataBean> list = crit.list(); }catch(Exception e){ System.err.println("Exception occured in setPlaylist "+ e); } finally { session.close(); }

I am not using get or load.
g wildin
Greenhorn

Joined: Jun 26, 2008
Posts: 3
I am a novice,but maybe the evict() method wouldn't be easy for your code. You might try the Session.clear() method mentioned below. I'm anxious to hear if it works for you. Here's what I found about this:

Any time an object passes through the Session instance, it's added to the Session�s cache. By passes through, we're referring to saving or retrieving the object to and from the database. To see whether an object is contained in the cache, call the Session.contains()method. Objects can be evicted from the cache by calling the Session.evict() method. Let's revisit the previous code, this time evicting the first Event instance:
Session session =factory.openSession();
Event firstEvent =(Event)session.load(Event.class,myEventId);
//...perform some operation on firstEvent
if (session.contains(firstEvent)){
session.evict(firstEvent);
}
Event secondEvent =new Event();
secondEvent.setId(myEventId);
session.save(secondEvent);
The code first opens the Session instance and loads an Event instance with a given ID. Next, it determines whether the object is contained in the Session cache and evicts the object if necessary. The code then creates a second Event instance with the same ID and successfully saves the second Event instance.
If you simply want to clear all the objects from the Session cache, you can call the aptly named Session.clear()method.
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Thanks g wildin for nice reply. Unfortunately, I have tried Session.flush and Session.clear but not getting the latest result.
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 10268
    
168

- Cache provider: org.hibernate.cache.EhCacheProvider

- Second-level cache: enabled


Somewhere in your xml's i guess you have configured hibernate.cache.provider_class to use EhCache. I believe that's the reason why the second level cache is enabled. Remove that property from the xml and see if its works.

For more debugging, you can enable Hibernate trace logs, as mentioned here. These logs will show you whether the queries are being fired to get the object from the database or they are being picked up from cache.


[My Blog] [JavaRanch Journal]
Sunil Kumar Gupta
Ranch Hand

Joined: Aug 26, 2005
Posts: 824
Originally posted by Jaikiran Pai:


Somewhere in your xml's i guess you have configured hibernate.cache.provider_class to use EhCache. I believe that's the reason why the second level cache is enabled. Remove that property from the xml and see if its works.


Hi Jaikiran, Thanks for replying.

I have checked my files, but i have not provided EhCache anywhere and the log i shared was coming when i don't use the below line

<property name="hibernate.cache.use_second_level_cache">false</property>

if i use this line, It shows that second level cache is disabled, yet i receive the old data only. I will check the link you shared with me.

Thanks.
Aamir Shah
Greenhorn

Joined: Aug 19, 2008
Posts: 3
I m facing same caching Problem sooo if any one has solution then please sent me...............
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Have you been through all the steps suggested above?
Hanna Habashy
Ranch Hand

Joined: Aug 20, 2003
Posts: 532
Are you warping your data access with transaction?

I know you are reading only, but it is recommended to wrap all data access with transaction.


SCJD 1.4<br />SCJP 1.4<br />-----------------------------------<br />"With regard to excellence, it is not enough to know, but we must try to have and use it.<br />" Aristotle
Aamir Shah
Greenhorn

Joined: Aug 19, 2008
Posts: 3
Yes i have followed all of these steps whenever i changed data from php application or Sql Query browser getting same cache data not updated......
But for some cases when i use session.evit method and session.flush method
the behavior changes and becomes more ambigious some times it shows updated data and some time older data.
I think hibernate keeps reference of both the object in memory.......
So in this case how to delete older reference Of object in memory.???
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336


I think hibernate keeps reference of both the object in memory.......
So in this case how to delete older reference Of object in memory.???

Yes, it does. The Hibernate Session is a first level cache. You sync the Session with the database by flushing it and commiting any transactions. See the Hibernate documentation for a full explanation.
Aamir Shah
Greenhorn

Joined: Aug 19, 2008
Posts: 3
Thank you very much I have sloved the problem.............
Alex Kruglov
Greenhorn

Joined: May 06, 2008
Posts: 8
Aamir Shah, what is a solution of your problem?
Ngoc Tiep Vu
Greenhorn

Joined: Nov 11, 2008
Posts: 6
Hello, i have the same problem too, can anyone help ?
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Please don't wake up old topics.

Sunil Kumar Gupta had two applications accessing the database, the Java one doing so through a web service backed by Hibernate. And he was using the second level cache. Is your application's architectrue the same (or simmilar) and have you tried all the suggestions listed above?
Ngoc Tiep Vu
Greenhorn

Joined: Nov 11, 2008
Posts: 6
Originally posted by Paul Sturrock:
Please don't wake up old topics.

Sunil Kumar Gupta had two applications accessing the database, the Java one doing so through a web service backed by Hibernate. And he was using the second level cache. Is your application's architectrue the same (or simmilar) and have you tried all the suggestions listed above?


Sorry for my inconvenience. But i have the same problem with Suni Kumar Gupta. I have try all suggestions in this thread, but these can not solve my problem.

In my application architecture, i have two different clients, that accessing the same database with hibernate. Each clients create its own Hibernate Session Factory. When a Client update new data, another client can only get the old data, except when i restart the another client (that means a new Session Factory was new created).

Here is my Hibernate Configuration:

<session-factory>


<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://...</property>
<property name="hibernate.connection.username">...</property>
<property name="hibernate.connection.password">...</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">false</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.cglib.use_reflection_optimizer">false</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.use_second_level_cache">false</property>

<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>


And cache status in hibernate log file:

Second-level cache: disabled
Query cache: disabled

Thank you for your helps.
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Post the code where you update your data.
Ngoc Tiep Vu
Greenhorn

Joined: Nov 11, 2008
Posts: 6
Originally posted by Paul Sturrock:
Post the code where you update your data.


Hello Paul,

Thank you very much for your replying. Here is my code for update data and load data:

[ November 14, 2008: Message edited by: Paul Sturrock ]
Satish Kandagadla
Greenhorn

Joined: Jul 03, 2006
Posts: 27
Have you tried checking the database after updating it with the first client? Is the data updated in the database?
[ November 14, 2008: Message edited by: Satish Kandagadla ]
Ngoc Tiep Vu
Greenhorn

Joined: Nov 11, 2008
Posts: 6
Originally posted by Satish Kandagadla:
Have you tried checking the database after updating it with the first client? Is the data updated in the database?

[ November 14, 2008: Message edited by: Satish Kandagadla ]


Yes, i have check the data in database server. After updating with the first client, data in database is updated, but the second client can read only the old data.
Satish Kandagadla
Greenhorn

Joined: Jul 03, 2006
Posts: 27
Originally posted by Ngoc Tiep Vu:


Yes, i have check the data in database server. After updating with the first client, data in database is updated, but the second client can read only the old data.


Did you use the same HibernateUtil class as the one posted in the Hibernate site or you have created one of your own? can you paste the code for HibernateUtil class?
Ngoc Tiep Vu
Greenhorn

Joined: Nov 11, 2008
Posts: 6
Originally posted by Satish Kandagadla:


Did you use the same HibernateUtil class as the one posted in the Hibernate site or you have created one of your own? can you paste the code for HibernateUtil class?


Hello,

Thank you for your reply. I have HibernateUtil class created. Here is the code:

[CODE]HibernateUtil
[QB]

public class HibernateUtil {

public static final String JNDI_SESSION_FACTORY_NAME = "...";
public static final String JNDI_CLASS = "...";
public static final String JNDI_URL = "...";

public static Configuration hibernateConfig = null;
public static SessionFactory sessionFactory = null;

/**
* Log4j logger
*/
private static Log logger = LogFactory.getLog(HibernateUtil.class);

/**
* Initialize hibernate configuration and create SessionFactory object
* @return true if success
*/
public static void setup() {

try {
// Check if the SessionFactory not exists then build it. The new SessionFactory is
// automatic binded with JNDI (see hibernate.cfg.xml)
if (getSessionFactory() == null) {

logger.info("creating hibernate session fatory...");
hibernateConfig = new Configuration().configure();

sessionFactory = hibernateConfig.buildSessionFactory();
}
}
catch (Throwable ex) {
logger.debug("HibernateUtil.setup: " + ex.getMessage());
throw new ExceptionInInitializerError(ex.getMessage());
}
}


/**
* Return the global SessionFactory
* @return SessionFactory
*/
public static SessionFactory getSessionFactory() {

return sessionFactory;
}

/**
* Close the current SessionFactory and release all resource.
* The other Functions schould not be called after calling of this function
*/
public static void shutdown () {

logger.info("close hibernate session fatory...");

if (sessionFactory != null)
sessionFactory.close();

sessionFactory = null;
hibernateConfig = null;
}
}
Mako Mako Makovic
Greenhorn

Joined: Feb 03, 2009
Posts: 1
I had the same problem and solved it putting query in transaction.

I hope it helps.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Problem with Hibernate Cache