-->
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.  [ 5 posts ] 
Author Message
 Post subject: Retrieving outdated data using session.load method
PostPosted: Fri Jun 30, 2006 8:07 am 
Beginner
Beginner

Joined: Fri Jun 30, 2006 6:54 am
Posts: 20
Location: Germany
Hello Forum,

making my first steps with hibernate I started developing a little knowledge
base application using Java, Swing and of course hibernate. The application has four tables: Users, Categories, Entries and Attachments. The categories and the entries held by the categories are visualized using a subclass of JTree and a subclass of DefaultMutableTreeNode. To prevent users from working on old data that might has been changed by another user I set up a TimerTask and associated an ActionListener on it that shall update the currently expanded node at given intervals. While implementing the code for the ActionPerformed method I encountered the following problem:

I start the application, expand a category and select a node wich is an object of my subclass of DefaultMutableTreeNode and that contains an user object of class Entry. The selected Entry object has the entry_id 2.

After that I change the title of the Entry in the database on the command line using:

UPDATE entry SET entry_title='ChangedValue' WHERE entry_id=2

After that I verified that the row contains the changed data using the PHPMyAdmin tool to look into the table.

The code in the ActionPerformed method of my TimerTask associated ActionListener
shall compare the object in the currently selected node with the one feteched from the databse an replace the object if
it has changed.

Hibernate version:
3.1.1
Mapping documents:

Hibernate config file:
Code:

<?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">
       
<hibernate-configuration>

    <session-factory>
   
        <!-- Define Db connection settings -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
        <property name="hibernate.connection.username">mainDBUser</property>
        <property name="hibernate.connection.password">xxxxxx</property>
        <property name="hibernate.connection.url">jdbc:mysql://jupiter.edvbm.local/jkb</property>
       
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">2</property>
       
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
       
         <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
       
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
       
        <!-- Define mappings -->
        <mapping resource="de/edvbm/jkb/util/data/pojos/Attachment.hbm.xml"/>
        <mapping resource="de/edvbm/jkb/util/data/pojos/Category.hbm.xml"/>
        <mapping resource="de/edvbm/jkb/util/data/pojos/Entry.hbm.xml"/>
        <mapping resource="de/edvbm/jkb/util/data/pojos/User.hbm.xml"/>

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



Mapping file of the Entry class

Code:

<?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 package="de.edvbm.jkb.util.data.pojos">

    <class name="Entry" table="entry">
   
        <id column="entry_Id" name="entryId" type="long">
            <generator class="native"/>
        </id>

        <property column="entry_created_by_user_Id" length="11" name="entryCreatedByUserId" not-null="true" type="integer"/>
        <property column="entry_category_id" length="11" name="entryCategoryId" not-null="true" type="integer"/>
        <property name="entryTitle" column="entry_title" length="255" type="string" not-null="true"/>
        <property name="entryText" column="entry_text" length="2147483647" type="string"/>
        <property name="entryCreationDate" column="entry_creation_date" type="java.util.Date" not-null="true"/>

    </class>
   
</hibernate-mapping>



Code between sessionFactory.openSession() and session.close():

Code:

TreePath currSelectedPath = tree.getSelectionPath();
       
    if (currSelectedPath != null) {
   
        JkbTreeNode currTreeNode = (JkbTreeNode) currSelectedPath.getLastPathComponent();
       
        Object currUserObject = currTreeNode.getUserObject();
               
            if (currUserObject instanceof Entry) {
                   
                Session session = context.getSessionFactory().openSession();
                   
                // Prevent reading from cache
                session.setCacheMode(CacheMode.IGNORE);
                   
                Entry entryFromNode = (Entry) currUserObject;
                   
                System.err.println("------------------- Loading object from db ---------\n");
                   
                Entry entryFromDb = (Entry) session.load(Entry.class, entryFromNode.getEntryId());
                   
                if (!entryFromNode.equals(entryFromDb)) {
                       
                    System.err.println("\n\nNODES ARE NOT EQUAL - Replacing node");
                    DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
                    currTreeNode.setUserObject(entryFromDb);
                    treeModel.reload(currTreeNode);
                }
                   
                session.close();
                   
            } // End if - Instance is of type Entry
       
    }



Full stack trace of any exception that occurs:

None

Name and version of the database you are using:

MySQL, 5.0.15-nt-max

The generated SQL (show_sql=true):

Code:

------------------- Loading object from db ---------
10:24:00,751 DEBUG SessionImpl:1291 - setting cache mode to: IGNORE

10:24:00,751 DEBUG DefaultLoadEventListener:153 - loading entity: [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,751 DEBUG DefaultLoadEventListener:230 - creating new proxy for entity
10:24:00,752 DEBUG JDBCContext:215 - after autocommit
10:24:00,752 DEBUG ConnectionManager:305 - aggressively releasing JDBC connection
10:24:00,752 DEBUG SessionImpl:440 - after transaction completion
10:24:00,753 DEBUG SessionImpl:843 - initializing proxy: [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,753 DEBUG DefaultLoadEventListener:304 - attempting to resolve: [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,754 DEBUG DefaultLoadEventListener:340 - object not resolved in any cache: [de.edvbm.jkb.util.data.pojos.Entry#2]
                                                         ^^
                                                          so it shall be loaded form the databse, or not?     

10:24:00,754 DEBUG AbstractEntityPersister:2723 - Fetching entity: [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,755 DEBUG Loader:1777 - loading entity: [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,756 DEBUG AbstractBatcher:311 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
10:24:00,756 DEBUG ConnectionManager:322 - opening JDBC connection
10:24:00,756 DEBUG DriverManagerConnectionProvider:93 - total checked-out connections: 0
10:24:00,757 DEBUG DriverManagerConnectionProvider:99 - using pooled JDBC connection, pool size: 0
10:24:00,757 DEBUG SQL:346 - select entry0_.entry_Id as entry1_2_0_, entry0_.entry_created_by_user_Id as entry2_2_0_, entry0_.entry_category_id as entry3_2_0_, entry0_.entry_titel as entry4_2_0_, entry0_.entry_text as entry5_2_0_, entry0_.entry_creation_date as entry6_2_0_ from entry entry0_ where entry0_.entry_Id=?
Hibernate: select entry0_.entry_Id as entry1_2_0_, entry0_.entry_created_by_user_Id as entry2_2_0_, entry0_.entry_category_id as entry3_2_0_, entry0_.entry_titel as entry4_2_0_, entry0_.entry_text as entry5_2_0_, entry0_.entry_creation_date as entry6_2_0_ from entry entry0_ where entry0_.entry_Id=?
10:24:00,758 DEBUG AbstractBatcher:424 - preparing statement
10:24:00,759 DEBUG LongType:79 - binding '2' to parameter: 1

10:24:00,764 DEBUG AbstractBatcher:327 - about to open ResultSet (open ResultSets: 0, globally: 0)
10:24:00,765 DEBUG Loader:682 - processing result set
10:24:00,765 DEBUG Loader:687 - result set row: 0
10:24:00,766 DEBUG Loader:1164 - result row: EntityKey[de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,766 DEBUG Loader:1347 - Initializing object from ResultSet: [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,767 DEBUG AbstractEntityPersister:1860 - Hydrating entity: [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,767 DEBUG IntegerType:123 - returning '1' as column: entry2_2_0_  <-- CreatedByUserId
10:24:00,768 DEBUG IntegerType:123 - returning '1' as column: entry3_2_0_  <-- CategoryId
10:24:00,770 DEBUG StringType:123 - returning 'OldData' as column: entry4_2_0_ <-- EntryTitle
                                                 ^^^
                                                  Why is it fetching the old data instead of the changed one?
                                                 
10:24:00,770 DEBUG StringType:123 - returning 'OldData' as column: entry5_2_0_ <-- EntryText
10:24:00,771 DEBUG TimestampType:123 - returning '2006-06-30 10:11:07' as column: entry6_2_0_
10:24:00,772 DEBUG Loader:709 - done processing result set (1 rows)
10:24:00,772 DEBUG AbstractBatcher:334 - about to close ResultSet (open ResultSets: 1, globally: 1)
10:24:00,773 DEBUG AbstractBatcher:319 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
10:24:00,773 DEBUG AbstractBatcher:470 - closing statement
10:24:00,774 DEBUG Loader:839 - total objects hydrated: 1
10:24:00,775 DEBUG TwoPhaseLoad:104 - resolving associations for [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,776 DEBUG TwoPhaseLoad:203 - done materializing entity [de.edvbm.jkb.util.data.pojos.Entry#2]
10:24:00,776 DEBUG StatefulPersistenceContext:820 - initializing non-lazy collections
10:24:00,776 DEBUG Loader:1808 - done entity load
10:24:00,777 DEBUG SessionImpl:292 - closing session



Debug level Hibernate log excerpt:

Code:

### direct log messages to stdout ###

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

# log4j.rootLogger=DEBUG, stdout
log4j.rootLogger=warn, stdout

#log4j.logger.org.hibernate=info
log4j.logger.org.hibernate=debug

### log cache activity ###
log4j.logger.org.hibernate.cache=debug



When I interpret the log messages correctly they tell me that the object isn't cached anywhere but if so I don't understand why the old data
is returend by the load method.

I searched the web, searched this forum but were unable to find hte reason for the behaviour.
Of course I read the documentation chapters 19.3 and 19.4 about the caches.

But when I get it right any new session has it's own cache - and I create a new session before issuing the load method on it
and I also have set the CacheMode to IGNORE.

Any help would be greatly appreciated.

Have a nice Weekend!

Henning Malzahn


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 30, 2006 8:58 am 
Expert
Expert

Joined: Tue Apr 25, 2006 12:04 pm
Posts: 260
Instead of manually updating database, try to have some utility code so that it updates the database but going through hibernate code. If you follow this approach then the session will return data as expected.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 30, 2006 9:59 am 
Beginner
Beginner

Joined: Fri Jun 30, 2006 6:54 am
Posts: 20
Location: Germany
Thank you for reading bkmr_77,

but that does not help.
Even when I change that Entry object using a second instance of my tool that uses another session and makes the changes using a transaction which completes successfully the first instance does not notice the changed record.

I use the following code to update the record:

Code:

    public void internalFrameClosing(final InternalFrameEvent e) {
       
        @SuppressWarnings("unused")
        SwingWorker swingWorker = new SwingWorker() {

            /* (non-Javadoc)
             * @see de.edvbm.jkb.util.gui.SwingWorker#construct()
             */
            @Override
            public Object construct() {
               
                Entry currEntry = null;
                Transaction ta = null;
               
                Session session = context.getSessionFactory().openSession();
                session.setCacheMode(CacheMode.IGNORE);
               
                try {
                   
                    // Load the object to edit
                    Entry tmpEntry = (Entry) currTreeNode.getUserObject();
                    currEntry = (Entry) session.load(Entry.class, tmpEntry.getEntryId());
                   
                    // Begin transaction and change
                    ta = session.beginTransaction();
                        currEntry.setEntryTitel(titelTxFld.getText());
                        currTreeNode.setUserObject(currEntry);
                    ta.commit();     
                }
                catch (Exception e) {
                    System.err.println("\n\nClass EntryEditInternalFrameListener "
                                       + "Exception thrown in method "
                                       + "internalFrameClosing() when trying "
                                       + "to update entry context\n\n");
                    e.printStackTrace();
                    if (ta != null) {
                        ta.rollback();
                    }
                }
                finally {

                    session.close();
                }

                return null;
               
            } // End of construct()

            /* (non-Javadoc)
             * @see de.edvbm.jkb.util.gui.SwingWorker#finished()
             */
            @Override
            public void finished() {
                super.finished();
               
                // Retrieve tree model
                DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
               
                // Reload changed node
                treeModel.reload(currTreeNode);
               
            } // End of finished()
           
        };
        swingWorker.start();

    } // End of internalFrameClosing()



Henning Malzahn


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 30, 2006 4:57 pm 
Beginner
Beginner

Joined: Fri Jun 30, 2006 6:54 am
Posts: 20
Location: Germany
Hello Forum,

found the problem - It was the built in connection pool of hibernate.

In my config I had the following entry:

Code:
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">2</property>


I changed that to:

Code:
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">0</property>


and everything began working as expected.

But I still wanted to use a connection pool so I switched to the c3p0 connection pool and configured it with:

Code:
<property name="hibernate.c3p0.min_size">2</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.acquire_increment">1</property>


And with that one everything works as expected!

Anyway - Thank you to all readers!

Have a nice weekend!

Henning Malzahn


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 06, 2006 3:20 pm 
Newbie

Joined: Thu Jul 06, 2006 11:30 am
Posts: 1
Actually, thank you! I just spent 6 hours today trying to figure out the same problem. You've saved me quite a bit of stress.


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