2

I'm working on Hibernate. I'm testing a simple Java to load 2 entities of book in 2 separate sessions. I loaded the first book object, let the main thread sleep 5s, during this time, I changed the name of the book in the db. After that, the second session would load the book again. But the name of the book is still the same. When it's expected to be changed also.

Please help. I wrote a servlet program but with the same issue, the updated data doesn't show after db change.

Here is my code:

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.CacheMode;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import org.hibernate.stat.Statistics;

/**
 * @author Guruzu
 * 
 */
public class Launch_3_5 {

    private static SessionFactory sessionFactory;

    public static Session getSession() {
        if (sessionFactory == null) {
            sessionFactory = new Configuration().configure()
                    .buildSessionFactory();
        }
        Session hibernateSession = sessionFactory.openSession();
        return hibernateSession;
    }

    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null) {
            sessionFactory = new Configuration().configure()
                    .buildSessionFactory();
        }
        return sessionFactory;
    }

    public static void main(String[] args) {
        Session session1 = getSessionFactory().openSession();

        try {

            Transaction tx = session1.beginTransaction();

            Book book1 = (Book) session1.get(Book.class, (long) 1);

            System.out.println("Book: " + book1.getName());


        //  session1.flush();
        } finally {

            session1.close();
        }

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Session session2 = getSessionFactory().openSession();

        try {

            Book book2 = (Book) session2.get(Book.class, (long) 1);
            System.out.println("Book: " + book2.getName());

        } finally {

            session2.close();
        }

    }
}

Book6_1.hbm.xml

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="Book" table="Book6_1">

        <id name="book_id" type="long" column="BOOK_ID">
            <generator class="increment">
            </generator>
        </id>
        <property name="isbn" type="string">
            <column name="ISBN" length="50" not-null="true" unique="true" />
        </property>
        <property name="name" type="string">
            <column name="BOOK_NAME" length="100" not-null="true" />
        </property>
        <property name="publishDate" type="date" column="PUBLISH_DATE" />
        <property name="price" type="int" column="PRICE" />


    </class>
</hibernate-mapping> 

hibernate.cfg.xml

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

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatetutorial</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.connection.pool_size">10</property>
        <property name="show_sql">true</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <mapping resource="Book_6_1.hbm.xml" />

    </session-factory>
</hibernate-configuration>

1 Answer 1

1

Your second session is hitting the second-level cache. If you don't want it to do so, you could turn off the cache entirely in your configuration file (use_second_level_cache = false) or mapping file (remove the 'cache' element from the hbm.xml).

Or you can change your query to always go to the database using CacheMode.REFRESH

    Session session2 = getSessionFactory().openSession();
    session2.setCacheMode(CacheMode.REFRESH);
    try {
        Book book2 = (Book) session2.get(Book.class, (long) 1);
    } finally {
        session2.close();
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Hi Sharakan, thanks for your help, actually I didn't use 2nd cache, I forgot to comment out it when posting my code. Sorry about that. I've edited my question. Please take a look again and help. Hibernate queries DB 2 times but the result is still the same.It seems that the problem is in the way I manage sessions.
I don't see any problems in the code or mapping file now. So your SQL log shows two select queries, both of the form 'select ... from Book6_1 where BOOK_ID = 1'? If so next thing to try is to make sure that your update is committed. If it's not, the second select wouldn't see the update. You could even try to run a select after the update in a separate query tool, to make sure the committed database state is as you expect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.