-->
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.  [ 6 posts ] 
Author Message
 Post subject: Problem with saving multiple objects in a session
PostPosted: Sat Jun 09, 2007 6:29 pm 
Newbie

Joined: Thu Jun 07, 2007 5:48 am
Posts: 3
Location: Sweden
Hi,

I am using Struts 2 + spring-hibernate + MySQL 5.x to develop an web-application. Using hibernate 3 + annotation for mapping the files.

Hibernate version: 3.2.4SP1

Mapping documents:
ApplicationContext.xml:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
  <!-- Hibernate SessionFactory -->
 
  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
      <property name="configurationClass">
          <value>org.hibernate.cfg.AnnotationConfiguration</value>
      </property>
      <property name="configLocation">
      <value>WEB-INF/classes/hibernate.cfg.xml</value>
    </property>
  </bean>
 
  <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->

  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
  </bean>

  <!-- ==BUSINESS OBJECT DEFINITIONS == -->

  <bean id="adminDao" lazy-init="true"
   class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"><ref local="transactionManager"/></property>
    <property name="target">
      <bean class="x.y.dao.AdminDaoImpl">
   <property name="sessionFactory"><ref local="sessionFactory"/></property>
      </bean>
    </property>
    <property name="transactionAttributes">
      <props>
   <prop key="add*">PROPAGATION_REQUIRED</prop>
   <prop key="delete*">PROPAGATION_REQUIRED</prop>
   <prop key="get*">PROPAGATION_REQUIRED</prop>
   <prop key="update*">PROPAGATION_REQUIRED</prop>
   <prop key="*">PROPAGATION_REQUIRED</prop>
      </props>
    </property>
  </bean>

</beans>


hibernate.cfg.xml:
Code:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
       
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">my_db</property>
        <property name="connection.username">my_user</property>
        <property name="connection.password">my_pass</property>

        <property name="dbcp.maxActive">4</property>
        <property name="dbcp.maxIdle">2</property>
        <property name="dbcp.maxWait">60000</property>
        <property name="dbcp.whenExhaustedAction">0</property>
        <property name="dbcp.ps.maxActive">30</property>
        <property name="dbcp.ps.maxIdle">15</property>
        <property name="dbcp.ps.maxWait">60000</property>
        <property name="dbcp.ps.whenExhaustedAction">0</property>
       
        <property name="hibernate.c3p0.min_size">5</property>
        <property name="hibernate.c3p0.max_size">20</property>
        <property name="hibernate.c3p0.timeout">300</property>
        <property name="hibernate.c3p0.max_statements">50</property>
        <property name="hibernate.c3p0.idle_test_period">3000</property>
       
        <property name="use_outer_join">true</property>   
        <property name="show_sql">true</property>
       
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
       
        <mapping class="x.y.db.AnsvPersonalObj"/>
        <mapping class="x.y.db.Objekt"/>
    </session-factory>
</hibernate-configuration>



I have a entity class like this:

AnsvPersonalObj.java
Code:
@Entity
@Table(name = "ansv_personal_obj")
public class AnsvPersonalObj implements Serializable {

    @Id
    @Column(name = "id", nullable = false)
    private long id;

    @JoinColumn(name = "objekt_id", referencedColumnName = "prim")
    @ManyToOne
    private Objekt objekt;

    ... ...
}


And i need to save a list of elements of this class in one transaction. So in my AdminDaoImpl class I wrote:

AdminDaoImpl.java:

Code:

    public void addAnsvPersonalObj(List apObjList) {
        Hibernate Template ht = this.getHibernateTemple();

        for (int i = 0; i < apObjList.size(); i++) {
             ht.save(apObjList.get(i));
        }
    }



While saveing more than one element at a time, I'm getting the following error:

Code:
javax.servlet.ServletException: a different object with the same identifier value was already associated with the session: [x.y.db.AnsvPersonalObj#0]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [x.y.db.AnsvPersonalObj#0]


The problem I have traced so far is, when one object is saved, it's id is still set to '0'. From the doc, after saving the object, the 'id' should be the set with the saved id from the database. As a result of this bug (!!!), when it tries to save the next object, the id clashes with the previous one (both of them has '0' in id, one saved object and other unsaved). By-the-way, according to the annotation doc, the unsaved-value is automatically set to '0', and Hibernate will know that this object is a new one from id '0'.

At this point, i want to add, I'm using MySQL 5.x, InnoDB and auto-increment for id generation.

The id generation works fine when only one object is saved. It is saved with a incremented value in the database, but the returned value still remains '0', so does the id of the saved object.

Can anyone please help me?

~ Arif


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 11, 2007 6:03 pm 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
Your problem is that you are generating the ID on the database side through what is essentially a trigger. Hibernate's session doesn't know about anything done outside of it which is why your ID of your object is still 0.

I'm not sure if there is a Hibernate ID type that accommodates the autogen scenario but I would think that's typically a less desirable id generation scheme.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 19, 2007 11:23 am 
Newbie

Joined: Thu Jun 07, 2007 5:48 am
Posts: 3
Location: Sweden
VampBoy wrote:
I'm not sure if there is a Hibernate ID type that accommodates the autogen scenario but I would think that's typically a less desirable id generation scheme.


Thanks for your reply. I understand what you want to say. Can you give me some idea, how can I generate id for MySQL using Hibernate Annotations. I used sequence before for Oracle, PostgreSQL and worked fine. But MySQL doesn't have anything like that. any workaround?

Thanks in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 2:37 pm 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
Unfortunately, I don't have any experience with MySql using Hibernate and my experience I have with MySql I want to forget :D

There are other id gen schemes, hi-lo, guid, etc but you may run into issues if other things are also using the db in question.

There might also be a way to pull the id back onto the record but I'm just speculating as I've never had to do anything like it myself.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 6:55 pm 
Newbie

Joined: Thu Jun 07, 2007 5:48 am
Posts: 3
Location: Sweden
I just got my code working. I added @GeneratedValue for @Id.

Now my class looks like this:

Code:
@Entity
@Table(name = "ansv_personal_obj")
public class AnsvPersonalObj implements Serializable {

    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false)
    private long id;

    @JoinColumn(name = "objekt_id", referencedColumnName = "prim")
    @ManyToOne
    private Objekt objekt;

    ... ...
}


Thanks to VampBoy again.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 7:11 pm 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
Excellent, glad you got it working. I missed that you didn't have the @GeneratedValue annotation.


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