-->
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.  [ 4 posts ] 
Author Message
 Post subject: Problem with TransientObjectException and Query.list
PostPosted: Tue Aug 30, 2005 9:05 am 
Newbie

Joined: Mon Aug 29, 2005 5:21 am
Posts: 9
I have a problem with querying some objects and creating a list of these objects. I sometimes get a "TransientObjectException" in the following code and can't reproduce the problem and do not really understand why the exception is thrown.

The Exception tells me "object references an unsaved transient instance - save the transient instance before flushing: de.pgew.netstructure.Controlunit" but I only query the database so it does not make sense to save anything.

I hope anybody can help me with this problem. If further information is necessary I will post it here.

Code:
// create connection
Session session=HibernateUtil.currentSession();
Transaction tx=session.beginTransaction();

// read devices
Query q=session.createQuery("from Device device where device.devicetype='splitter'");
Device[] splitters=(Device[])q.list().toArray(new Device[]{});

// close connection
tx.commit();
HibernateUtil.closeSession();



Hibernate version:
3

Mapping documents:
Code:
// Only part of the document
<class name="de.pgew.netstructure.Device" table="netstructure_device">
  <id name="id" type="java.lang.Integer">
    <column name="id" length="11" not-null="true" unique="true" sql-type="int" />
    <generator class="native">
      <param name="sequence">netstructure_device_sequence</param>
    </generator>
  </id>
   
  <property name="devicetype" type="java.lang.String">
    <column name="devicetype" length="9" not-null="true" sql-type="enum" />
  </property>

  <property name="voltage" type="java.lang.String">
    <column name="voltage" length="11" not-null="false" sql-type="enum" />
  </property>

  <property name="location" type="java.lang.String">
    <column name="location" length="200" not-null="true" sql-type="varchar" />
  </property>

  <property name="externalID" type="java.lang.String">
    <column name="externalID" length="200" not-null="false" sql-type="varchar" />
  </property>

  <many-to-one name="controlunit" column="controlunit" not-null="true"/>

  <set name="cables" inverse="true">
    <key column="id"/>
    <one-to-many class="de.pgew.netstructure.Cable"/>
  </set>
</class>

<class name="de.pgew.netstructure.Controlunit" table="netstructure_controlunit" lazy="false">
  <id name="Id" type="java.lang.Integer">
    <column name="id" length="11" not-null="true" unique="true" sql-type="int" />
    <generator class="native">
      <param name="sequence">netstructure_cunit_sequence</param>
    </generator>
  </id>
   
  <property name="externalID" type="java.lang.String">
    <column name="externalID" length="11" not-null="true" sql-type="varchar" />
  </property>   

  <set name="devices" inverse="true">
    <key column="id"/>
    <one-to-many class="de.pgew.netstructure.Device"/>
  </set>
   
</class>



Full stack trace of any exception that occurs:
Code:
-> Exception org.hibernate.TransientObjectException occured
org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:216)
org.hibernate.type.EntityType.getIdentifier(EntityType.java:99)
org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:63)
org.hibernate.persister.entity.BasicEntityPersister.dehydrate(BasicEntityPersister.java:1617)
org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:1963)
org.hibernate.persister.entity.BasicEntityPersister.updateOrInsert(BasicEntityPersister.java:1909)
org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:2149)
org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:75)
org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:137)
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:48)
org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:711)
org.hibernate.impl.SessionImpl.prepareQueries(SessionImpl.java:895)
org.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:885)
org.hibernate.impl.SessionImpl.list(SessionImpl.java:834)
org.hibernate.impl.QueryImpl.list(QueryImpl.java:74)
de.pgew.netstructure.NetStructureDevice.getAllSplitters(NetStructureDevice.java:347)
...


Name and version of the database you are using:
Oracle 9i[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 30, 2005 9:29 am 
Pro
Pro

Joined: Mon Jan 24, 2005 5:39 am
Posts: 216
Location: Germany
Hi,

I am certainly not an expert.
Its a matter of the FlushMode.
Usually its Auto meaning:

Quote:
/**
* The <tt>Session</tt> is sometimes flushed before query execution
* in order to ensure that queries never return stale state. This
* is the default flush mode.
*/


So if you execute your query, your objects
are flushed to db indicate by the line

Quote:
org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:711)

in your stacktrace. And since you reference
transient objects you get that exception.

hope this helps.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 30, 2005 10:40 am 
Newbie

Joined: Mon Aug 29, 2005 5:21 am
Posts: 9
Thank you for your answer. This seems really to be the problem and explains why the Exception is not always thrown. I changed the source code to the following and hope it will work now:

Code:
// create connection
Session session=HibernateUtil.currentSession();
FlushMode oldFM=session.getFlushMode();
Transaction tx=session.beginTransaction();
Transaction tx=session.beginTransaction();

// read devices
Query q=session.createQuery("from Device device where device.devicetype='splitter'");
Device[] splitters=(Device[])q.list().toArray(new Device[]{});

// close connection
tx.commit();
session.setFlushMode(oldFM);
HibernateUtil.closeSession();


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 30, 2005 10:41 am 
Newbie

Joined: Mon Aug 29, 2005 5:21 am
Posts: 9
I wanted to post this:
Code:
// create connection
Session session=HibernateUtil.currentSession();
FlushMode oldFM=session.getFlushMode();
session.setFlushMode(FlushMode.NEVER);
Transaction tx=session.beginTransaction();

// read devices
Query q=session.createQuery("from Device device where device.devicetype='splitter'");
Device[] splitters=(Device[])q.list().toArray(new Device[]{});

// close connection
tx.commit();
session.setFlushMode(oldFM);
HibernateUtil.closeSession();


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