-->
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.  [ 7 posts ] 
Author Message
 Post subject: Inoperative UPDATE statements (cannot update)
PostPosted: Wed Jun 18, 2008 9:40 am 
Beginner
Beginner

Joined: Wed Jun 11, 2008 4:43 am
Posts: 20
Hi,
I use Hibernate with HSQLDB in standalone mode to persist my model. I am able to create the database, to add or remove some data but not to update a record. When I modify my model and persist the change using flush, then exit and then reload the model, all my changes made through UPDATE statements seem to have been inoperative. There is no exception thrown, no errors reported, the statement (see below) seems correct, the logs are not surprising me... All seems to be ok but nothing happens.
Any advice on what I should check to solve this issue?

Thx

Hibernate version: 3.2.6

Name and version of the database you are using: Standalone HSQLDB 1.8.0.8

The generated SQL (show_sql=true): Hibernate: update Environment set name=?, description=? where ENV_ID=?

Debug level Hibernate log excerpt:
Code:
14:46:06,750 DEBUG AbstractFlushingEventListener:58 - flushing session
14:46:06,750 DEBUG AbstractFlushingEventListener:111 - processing flush-time cascades
14:46:06,750 DEBUG AbstractFlushingEventListener:154 - dirty checking collections
14:46:06,765 DEBUG AbstractFlushingEventListener:171 - Flushing entities and processing referenced collections
14:46:06,765 DEBUG AbstractEntityPersister:3188 - org.myproject.model.Environment.name is dirty
14:46:06,765 DEBUG DefaultFlushEntityEventListener:236 - Updating entity: [org.myproject.model.Environment#1]
14:46:06,765 DEBUG AbstractFlushingEventListener:210 - Processing unreferenced collections
14:46:06,765 DEBUG AbstractFlushingEventListener:224 - Scheduling collection removes/(re)creates/updates
14:46:06,781 DEBUG AbstractFlushingEventListener:85 - Flushed: 0 insertions, 1 updates, 0 deletions to 5 objects
14:46:06,781 DEBUG AbstractFlushingEventListener:91 - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
14:46:06,781 DEBUG Printer:83 - listing entities:
14:46:06,781 DEBUG Printer:90 - org.myproject.model.Environment{description=Describe the environment here, name=ENV_4, id=4}
14:46:06,781 DEBUG Printer:90 - org.myproject.model.Environment{description=Describe the environment here, name=ENV_3, id=3}
14:46:06,781 DEBUG Printer:90 - org.myproject.model.ModelStatus{modelVersion=1, id=1}
14:46:06,781 DEBUG Printer:90 - org.myproject.model.Environment{description=Describe the environment here, name=ENV_5, id=1}
14:46:06,781 DEBUG Printer:90 - org.myproject.model.Environment{description=Describe the environment here, name=ENV_2, id=2}
14:46:06,781 DEBUG AbstractFlushingEventListener:290 - executing flush
14:46:06,781 DEBUG ConnectionManager:469 - registering flush begin
14:46:06,796 DEBUG AbstractEntityPersister:2344 - Updating entity: [org.myproject.model.Environment#1]
14:46:06,796 DEBUG AbstractBatcher:366 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
14:46:06,796 DEBUG ConnectionManager:421 - opening JDBC connection
14:46:06,796 DEBUG DriverManagerConnectionProvider:93 - total checked-out connections: 0
14:46:06,796 DEBUG DriverManagerConnectionProvider:99 - using pooled JDBC connection, pool size: 0
14:46:06,796 DEBUG SQL:401 - update Environment set name=?, description=? where ENV_ID=?
14:46:06,796 DEBUG AbstractBatcher:484 - preparing statement
14:46:06,796 DEBUG AbstractEntityPersister:1997 - Dehydrating entity: [org.myproject.model.Environment#1]
14:46:06,796 DEBUG StringType:133 - binding 'ENV_5' to parameter: 1
14:46:06,796 DEBUG StringType:133 - binding 'Describe the environment here' to parameter: 2
14:46:06,796 DEBUG LongType:133 - binding '1' to parameter: 3
14:46:06,812 DEBUG AbstractBatcher:44 - Executing batch size: 1
14:46:06,828 DEBUG AbstractBatcher:374 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
14:46:06,828 DEBUG AbstractBatcher:533 - closing statement
14:46:06,828 DEBUG ConnectionManager:478 - registering flush end
14:46:06,828 DEBUG AbstractFlushingEventListener:321 - post flush


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 18, 2008 10:22 am 
Beginner
Beginner

Joined: Tue Dec 12, 2006 6:43 am
Posts: 32
Location: London
Hi,

Can you please post the full code with the mapping to take a look.

Can you try to user tx.commit() instead of flushing the session.


Regards,

_________________
Alan Mehio
London
UK


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 18, 2008 10:58 am 
Beginner
Beginner

Joined: Wed Jun 11, 2008 4:43 am
Posts: 20
Here is the (very simple) mapping file:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.myproject.model">

  <class name="Environment">
     <id column="ENV_ID" name="id">
        <generator class="increment"></generator>
     </id>
     <property name="name"></property>
     <property name="description"></property>
  </class>
</hibernate-mapping>


For the moment, I use a single session for my application (bad boy!). When I change something in my model (that is not aware of any Hibernate stuff), it triggers a change event the handler of which does almost nothing but a flush:
Code:
public void updateEntry(Object entry) {
   try {
      session.flush();
   } catch (HibernateException e) {
      logger.error("Could not flush on the update of an instance of class "+entry.getClass());
      logger.error("Caused by: "+e);
   }
}

I tried with a commit, but it didn't helped:
Code:
public void updateEntry(Object entry) {
   try {
      session.beginTransaction();
      session.getTransaction().commit();
   } catch (HibernateException e) {
      logger.error("Could not flush on the update of an instance of class "+entry.getClass());
      logger.error("Caused by: "+e);
   }
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 18, 2008 7:57 pm 
Beginner
Beginner

Joined: Wed Jun 11, 2008 4:43 am
Posts: 20
Ok, I tried to use a session-per-operation pattern. Of course, it helped solving the update problem, but now I have problems with lazy collection handling (session is closed when I access to the collection).
No other idea?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 19, 2008 12:42 am 
Newbie

Joined: Wed Jun 18, 2008 1:43 am
Posts: 3
If you are reading and updating the same object at two different places then may be you want to refresh the object that you are gonna read after the update operation.

Suppose you get an object:
Object obj = DB.get();
...................
...................
..................

obj.getProperty();

After getting the object from database and before reading the object meanwhile if someone updates the object in the database then to get the latest version of object you have to refresh this item by attaching it to the current hibernate session.


Object obj = DB.get();
..................
.................
hibernateSession.refresh(obj);
obj.getProperty();


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 20, 2008 8:08 am 
Beginner
Beginner

Joined: Wed Jun 11, 2008 4:43 am
Posts: 20
Thanks for your reply but I would prefer to stay in a session-per-conversation pattern.

I finally get it to work by using the "merge" instead of a simple flush.
I reworked all the thing and have now a nice persistance layer (see the code below). In the model persister class, I instanciate this abstract class by providing the load and create methods.

I still have some problems in some occasions (the latest is the addition of an element, see below) and am still trying to understand why I do not get any warning or exception when a given DB operation fails (or at least has no effect in the DB)... May it be a HSQLDB problem?

Code:
package org.myproject.model.persister;

import org.apache.log4j.Logger;
import org.myproject.model.exceptions.VersionMismatchException;
import org.myproject.model.interfaces.IModelUpdateEventProvider;
import org.myproject.model.interfaces.IModelUpdateListener;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

/**
* This abstract class defines the necessary methods for persisting a data
* model using Hibernate. It uses the session-per-conversation pattern.<br/>
* The user shall provide the abstract methods load and create. The
* VersionMismatchException exception may be thrown if the persister
* implementation detects a mismatch between the data model in the database
* and the data model used by the application.<br/>
* When the conversation is ended, the user shall call the dispose method
* to free the hibernate session and session factories.<br/>
* When an exception is thrown, the application should either exit or reload
* the model.<br/>
*
* @param <Model> A model class to persist. This model should implement the
* IModelUpdateEventProvider interface and trigger the addEntry, removeEntry
* and updateEntry callbacks when an element has been added, removed or
* modified.
*/
public abstract class Persister<Model> implements IModelUpdateListener {

   /**
    * A logger
    */
   private static final Logger logger = Logger.getLogger(Persister.class);

   /**
    * The current hibernate session (session-per-conversation pattern).
    * We assume hibernate is configured with:
    *  - hibernate.connection.release_mode = after_transaction
    */
   protected Session session = null;

   /**
    * The model to persist
    */
   protected Model model;

   /**
    * The hibernate session factory.
    */
   protected SessionFactory sessionFactory = null;

   public Persister(Model model) {
      this.model = model;
      ((IModelUpdateEventProvider)model).addModelUpdateListener(this);
   }

   /**
    * Disposing the persister will close the session and the session factory
    * that is used by this instance. It should be called before exiting the
    * application or when the conversion is ended.<br/>
    * Accessing to collections in the model after calling this method should
    * be made carefully as some collection may not have been loaded due to
    * lazy collection handling in Hibernate. 
    */
   public void dispose() {

      // Unregister for model modification events
      ((IModelUpdateEventProvider)model).removeModelUpdateListener(this);

      // Close the session
      if (session!=null) {
         session.flush(); // necessary?
         session.close();
         session = null;
      }

      // Close the session factory
      if (sessionFactory!=null) {
         sessionFactory.close();
         sessionFactory = null;
      }
   }

   /**
    * This method creates the session factory, opens a session and loads the
    * model from the database.<br/>
    * @param databaseURL
    *             The URL of the database from which to load the model for
    *             this instance of persister.
    * @throws VersionMismatchException
    *             If the persister detects that the database structure is not
    *             as expected.
    */
   public abstract void load(String databaseURL) throws VersionMismatchException;

   /**
    * This method creates the session factory, opens a session and creates
    * the model in the database.<br/>
    * @param databaseURL
    *             The URL of the database to create and manage within this
    *             instance.
    */
   public abstract void create(String databaseURL);

   /**
    * Get the persisted model.
    * @return The model that is persisted by this instance.
    */
   public Model getModel() {
      return model;
   }

   /*
    * (non-Javadoc)
    * @see org.myproject.model.interfaces.IModelUpdateListener#addEntry(java.lang.Object)
    */
   public void addEntry(Object entry) {
      logger.debug("addEntry IN: "+entry);

      try {
         session.beginTransaction();
         session.save(entry);
         session.getTransaction().commit();
      } catch (HibernateException e) {
         logger.error("Could not persist instance of class "+entry.getClass());
         logger.error("Caused by: "+e);
         session.getTransaction().rollback();
         dispose();
         throw e;
      }

      logger.debug("addEntry OUT: "+entry);
   }

   /*
    * (non-Javadoc)
    * @see org.myproject.model.interfaces.IModelUpdateListener#removeEntry(java.lang.Object)
    */
   public void removeEntry(Object entry) {
      logger.debug("removeEntry IN: "+entry);

      try {
         session.beginTransaction();
         session.delete(entry);
         session.getTransaction().commit();
      } catch (HibernateException e) {
         logger.error("Could not delete instance of class "+entry.getClass());
         logger.error("Caused by: "+e);
         session.getTransaction().rollback();
         dispose();
         throw e;
      }

      logger.debug("removeEntry OUT: "+entry);
   }

   /*
    * (non-Javadoc)
    * @see org.myproject.model.interfaces.IModelUpdateListener#updateEntry(java.lang.Object)
    */
   public void updateEntry(Object entry) {
      logger.debug("updateEntry IN: "+entry);

      try {
         session.beginTransaction();
         session.merge(entry);
         session.getTransaction().commit();
      } catch (HibernateException e) {
         logger.error("Could not flush on the update of an instance of class "+entry.getClass());
         logger.error("Caused by: "+e);
         session.getTransaction().rollback();
         dispose();
         throw e;
      }

      logger.debug("updateEntry OUT: "+entry);
   }

}


Code:
12:38:44,144 DEBUG Persister:69 - addEntry IN: org.myproject.model.Environment@15386c2
12:38:44,144 DEBUG JDBCTransaction:54 - begin
12:38:44,144 DEBUG ConnectionManager:421 - opening JDBC connection
12:38:44,160 DEBUG DriverManagerConnectionProvider:93 - total checked-out connections: 0
12:38:44,160 DEBUG DriverManagerConnectionProvider:99 - using pooled JDBC connection, pool size: 0
12:38:44,160 DEBUG JDBCTransaction:59 - current autocommit status: false
12:38:44,160 DEBUG JDBCContext:214 - after transaction begin
12:38:44,160 DEBUG DefaultSaveOrUpdateEventListener:158 - saving transient instance
12:38:44,160 DEBUG IncrementGenerator:80 - fetching initial value: select max(ENV_ID) from Environment
12:38:44,160 DEBUG AbstractBatcher:366 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
12:38:44,160 DEBUG SQL:401 - select max(ENV_ID) from Environment
12:38:44,160 DEBUG AbstractBatcher:484 - preparing statement
12:38:44,160 DEBUG IncrementGenerator:95 - first free id: 1
12:38:44,160 DEBUG AbstractBatcher:374 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
12:38:44,160 DEBUG AbstractBatcher:533 - closing statement
12:38:44,160 DEBUG AbstractSaveEventListener:112 - generated identifier: 1, using strategy: org.hibernate.id.IncrementGenerator
12:38:44,160 DEBUG AbstractSaveEventListener:153 - saving [org.myproject.model.Environment#1]
12:38:44,191 DEBUG JDBCTransaction:103 - commit
12:38:44,191 DEBUG SessionImpl:337 - automatically flushing session
12:38:44,191 DEBUG AbstractFlushingEventListener:58 - flushing session
12:38:44,191 DEBUG AbstractFlushingEventListener:111 - processing flush-time cascades
12:38:44,191 DEBUG AbstractFlushingEventListener:154 - dirty checking collections
12:38:44,191 DEBUG AbstractFlushingEventListener:171 - Flushing entities and processing referenced collections
12:38:44,191 DEBUG AbstractFlushingEventListener:210 - Processing unreferenced collections
12:38:44,191 DEBUG AbstractFlushingEventListener:224 - Scheduling collection removes/(re)creates/updates
12:38:44,191 DEBUG AbstractFlushingEventListener:85 - Flushed: 1 insertions, 0 updates, 0 deletions to 7 objects
12:38:44,191 DEBUG AbstractFlushingEventListener:91 - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
12:38:44,191 DEBUG Printer:83 - listing entities:
12:38:44,191 DEBUG Printer:90 - org.myproject.model.RCSEntry{criterias=No safety impact, severity=5, id=3}
12:38:44,191 DEBUG Printer:90 - org.myproject.model.RCSEntry{criterias=Loss of separation (more than half), severity=2, id=5}
12:38:44,191 DEBUG Printer:90 - org.myproject.model.Environment{description=Describe the environment here, name=ENV_1, id=1}
12:38:44,191 DEBUG Printer:90 - org.myproject.model.RCSEntry{criterias=Controler workload increase, severity=4, id=1}
12:38:44,191 DEBUG Printer:90 - org.myproject.model.RCSEntry{criterias=Accident, severity=1, id=2}
12:38:44,191 DEBUG Printer:90 - org.myproject.model.RCSEntry{criterias=Loss of separation (less than half), severity=3, id=4}
12:38:44,191 DEBUG Printer:90 - org.myproject.model.ModelStatus{modelVersion=2, id=1}
12:38:44,191 DEBUG AbstractFlushingEventListener:290 - executing flush
12:38:44,191 DEBUG ConnectionManager:469 - registering flush begin
12:38:44,191 DEBUG AbstractEntityPersister:2209 - Inserting entity: [org.myproject.model.Environment#1]
12:38:44,332 DEBUG AbstractBatcher:366 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
12:38:44,332 DEBUG SQL:401 - insert into Environment (name, description, ENV_ID) values (?, ?, ?)
12:38:44,332 DEBUG AbstractBatcher:484 - preparing statement
12:38:44,332 DEBUG AbstractEntityPersister:1997 - Dehydrating entity: [org.myproject.model.Environment#1]
12:38:44,332 DEBUG StringType:133 - binding 'ENV_1' to parameter: 1
12:38:44,332 DEBUG StringType:133 - binding 'Describe the environment here' to parameter: 2
12:38:44,332 DEBUG LongType:133 - binding '1' to parameter: 3
12:38:44,332 DEBUG AbstractBatcher:44 - Executing batch size: 1
12:38:44,332 DEBUG AbstractBatcher:374 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
12:38:44,332 DEBUG AbstractBatcher:533 - closing statement
12:38:44,332 DEBUG ConnectionManager:478 - registering flush end
12:38:44,332 DEBUG AbstractFlushingEventListener:321 - post flush
12:38:44,332 DEBUG JDBCContext:205 - before transaction completion
12:38:44,348 DEBUG SessionImpl:393 - before transaction completion
12:38:44,348 DEBUG JDBCTransaction:116 - committed JDBC Connection
12:38:44,348 DEBUG JDBCContext:219 - after transaction completion
12:38:44,348 DEBUG ConnectionManager:404 - aggressively releasing JDBC connection
12:38:44,348 DEBUG ConnectionManager:441 - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
12:38:44,348 DEBUG DriverManagerConnectionProvider:129 - returning connection to pool, pool size: 1
12:38:44,348 DEBUG SessionImpl:422 - after transaction completion
12:38:44,348 DEBUG Persister:81 - addEntry OUT: org.myproject.model.Environment@15386c2


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 23, 2008 7:06 am 
Beginner
Beginner

Joined: Wed Jun 11, 2008 4:43 am
Posts: 20
It seems to happen when I am running out of resources. But still, I do not understand why I do not get any exception nor error. And I can't determine if it comes from Hibernate or, more probably, from the JDBC driver...


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