-->
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.  [ 8 posts ] 
Author Message
 Post subject: Bug in Hibernate implementation: Persisting an entity
PostPosted: Tue Jun 05, 2007 2:13 pm 
Beginner
Beginner

Joined: Tue May 08, 2007 1:20 pm
Posts: 24
Hibernate version:3.2

Mapping documents:
Code:
<id name="id" type="long" unsaved-value="0">
            <column name="ID" precision="10" scale="0" />
            <generator class="sequence">
                <param name="sequence">MY_SEQ</param>
            </generator>
        </id>

Code between sessionFactory.openSession() and session.close():
Code:
public void persist(
        DeviceType entity) {
        hibernateTemplate.persist(entity);
    }

Full stack trace of any exception that occurs:
Code:
<detached entity passed to persist: com.boeing.nmt.nams.model.DeviceType; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.boeing.nmt.nams.model.DeviceType>

Name and version of the database you are using: Oracle 10g

The generated SQL (show_sql=true): Doesnt show sql as it resulted in Exception

Debug level Hibernate log excerpt:org.hibernate.PersistentObjectException: detached entity passed to persist

I am able to persist the object successfully ONLY for the First time. And it throws an exception when i persist the object for second time or subsequent times.

The workaround solution is to explicitly set the value of Id to 0 i.e. setId(0) . But i think this is ugly solution . So Hibernate Gurus any pointers/suggestions will be highly appreciated

Regards
Bansi


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 05, 2007 2:28 pm 
Regular
Regular

Joined: Wed Nov 17, 2004 11:49 am
Posts: 65
Location: Pittsburgh
After the first time, you need to session.update() the object. by setting the primary key (id attribute) to null, you are actually inserting a new row in the database.

From the javadocs:
Quote:
Make a transient instance persistent. This operation cascades to associated instances if the association is mapped with cascade="persist".

The semantics of this method are defined by JSR-220.


Note that your object (after the first persiste()) is *detached* not transient.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 05, 2007 4:50 pm 
Beginner
Beginner

Joined: Tue May 08, 2007 1:20 pm
Posts: 24
Hi Kerstetter
Thanks for providing your thoughts
I am using Spring's Hibernate Template to do persist. And as you correctly suggested i am setting the primary key (id attribute) to 0 i.e. setId(0) to persist subsequent records, otherwise it will persist only first time.

Now my question is
Why do i need to set the primary key (id attribute) value to 0 for persisting subsequent records ???

How does Hibernate work in persisting subsequent records ???

Doesn't it uses simple intelligence to increment the id attribute based on the Sequence generator as defined in Hibernate mapping file

The Bug i am refering to is
When you persist the object for first time , the primary key of the object is remembered and marked as a sort of "already used" state and is used for subsequent persistence

The workaround is to explicitly set the value of id attribute to 0 which i think is pretty ugly solution.
This resolves the exception: detached entity passed to persist.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 05, 2007 4:56 pm 
Regular
Regular

Joined: Wed Nov 17, 2004 11:49 am
Posts: 65
Location: Pittsburgh
What I am trying to tell you is that calling persist generates an insert SQL statement and inserts a new row into the database. If you didn't get an exception from Hibenrate in this case, you'd get a PK constriant violation from the database.

By setting the id to zero, you are essentially bypassing this logic and forcing Hibernate to copy new rows to the database, which is probably not what you want. It may be, thats not entirely clear to me.

What I am guessing you want is for hibernate to update the current object in the database. For that, you can't use persist() you need to use merge() or saveOrUpdate() or update(). This will result in an update SQL statement.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 08, 2007 6:53 pm 
Beginner
Beginner

Joined: Tue May 08, 2007 1:20 pm
Posts: 24
Thanks for the info.
saveOrUpdate() method to save subsequent records works fine.

But i have problems with the Update i.e. updating associated objects results in updating of one object and insertion of associated object.
For example
The associated objects in my case are DeviceType and DeviceTypeRoles. Here is the sequence of method calls to update associated objects
In JSF Backing Bean
Code:
public void updateDeviceType(){
     deviceType.setId(Long.valueOf(selectedDeviceType));
     deviceType.setDeviceTypeRoles(createDeviceTypeRoleSet());
     deviceTypeManager.updateDeviceType(deviceType);
     this.deleteBtnMode = true;
     FacesUtils.addInfoMessage("update", "DeviceType", deviceType.getName());
  }

public Set createDeviceTypeRoleSet()
   {
      //System.out.println("In RoleList method ");
       //Iterator it = deviceRoles.iterator();
        //List roleList = new ArrayList();
      Set deviceTypeRoleSet = new HashSet();
       deviceTypeRole = new DeviceTypeRole();
        System.out.println("In Backing Bean: Adding Roles To Device Type, RoleSet Size="+getDeviceRoles()+""+deviceRoles);
        for (Iterator iter = deviceRoles.iterator(); iter.hasNext();) {
          System.out.println("Inside for loop");
            SelectItem selectItem = (SelectItem) iter.next();
            String roleId = (String)selectItem.getValue();
            System.out.println("In createDeviceTypeRoleSet method roleId= "+roleId);
            deviceTypeRole = deviceTypeManager.addRoleToDeviceType(Long.valueOf(roleId));            
            deviceTypeRole.setDeviceType(deviceType);            
            deviceTypeRoleSet.add(deviceTypeRole);
            //roleList.add(selectItem.getValue());
            }
        System.out.println("In createDeviceTypeRoleSet method Set size="+deviceTypeRoleSet.size());
       //return new HashSet(roleList);
        return deviceTypeRoleSet;
   }


In Spring Bean
Code:

public void updateDeviceType(DeviceType deviceType){
         logger.info(" *** In updateDeviceType Manager method *** ");
         System.out.println(" *** In updateDeviceType Manager method *** ");   
         deviceType.setNamsUser(baseManager.getNamsUserByChangeUserId());
         deviceType.setChangeDate(new Date());
         deviceTypeDao.update(deviceType);
      }

public DeviceTypeRole addRoleToDeviceType(Long roleId){
         System.out.println("In addRoleToDeviceType method");
         DeviceTypeRole deviceTypeRole = new DeviceTypeRole();
         try{
            NamsRole namsRole = namsRoleDao.get(roleId);
            System.out.println("RoleName in addRoleToDeviceType="+namsRole.getName());
            deviceTypeRole.setNamsRole(namsRole);
            deviceTypeRole.setNamsUser(baseManager.getNamsUserByChangeUserId());
               deviceTypeRole.setChangeDate(new Date());
            
         }catch(Exception e){
            logger.error(e.getMessage());
         }
         return deviceTypeRole;
      }


In HibernateImpl
Code:
public void update( DeviceType object) {
        hibernateTemplate.update(object);
    }

Hibernate Mapping File
Code:
<set name="deviceTypeRoles"  inverse="true"  cascade="save-update">
            <key>
                <column name="DEV_TYPE_ID" precision="10" scale="0" not-null="true" />
            </key>
            <one-to-many class="com.boeing.nmt.nams.model.DeviceTypeRole" />
        </set>


Hibernate Named Queries
Code:
<query name="findDeviceTypes">
        <![CDATA[
            from com.xxx.model.DeviceType dt order by dt.name
        ]]>
    </query>       
   
    <query name="findDeviceTypeRoles">
        <![CDATA[
            from com.xx.model.DeviceTypeRole dtr
            left join fetch dtr.namsRole
            left join fetch dtr.deviceType
            where dtr.deviceType.id = :deviceTypeId
        ]]>
    </query> 


I do have cascade="save-update" defined in mapping file.
Whenever i update not sure why associated object is doing insert instead of update . Here is the log
Code:
Hibernate: insert into DEVICE_TYPE_ROLE (CHANGE_USER, ROLE_ID, DEV_TYPE_ID, CHANGE_DATE, ID) values (?, ?, ?, ?, ?)
Hibernate: update DEVICE_TYPE set CHANGE_USER=?, NAME=?, DESCRIPTION=?, CHANGE_DATE=? where ID=?


Any pointers/suggestions will be highly appreciated

Regards
Bansi


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 11, 2007 8:32 am 
Regular
Regular

Joined: Wed Nov 17, 2004 11:49 am
Posts: 65
Location: Pittsburgh
It is issuing an insert on the DeviceTypeRole because you are newing up the role here:

Code:
System.out.println("In addRoleToDeviceType method");
DeviceTypeRole deviceTypeRole = new DeviceTypeRole();


If you want this to be an update, you have to have the data in the database already and you need to associate the DeviceType with the data in the database by first doing a find on the data, like:

Code:
session.get(DeviceTypeRole.class, pk);



***Don't forget to give credit***

I suggest you read through some of the Hibernate documentation. There are some pretty good examples of what you need to do in most introductory Hibernate books and in the online user's guide.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 12, 2007 12:22 pm 
Beginner
Beginner

Joined: Tue May 08, 2007 1:20 pm
Posts: 24
Thats perfect. The insertion doesn't happen anymore but the problems with update still exists.

Wondering how update works in case of associated objects.
Let say if Parent object ( in my case DeviceType) is associated with 3 records of Child object ( in my case Role)i.e. A DeviceType has 3 Roles.
During update if i add or delete one Role . Will this be taken care by cascade="save-update" ???
I mean next time will it say Parent object is associated with 2 or 4 records of Child object . In my case this is not happening i.e It always associated with 3 child records i.e. their is no effect of update

Here is the Situation
I have two list boxes (i.e. JSF h:selectManyListBox) to display All Roles and DeviceType Roles

Duringupdate,
-> i add/delete DeviceTypeRole from All Roles ,
-> i store the DeviceTypeRoles in a List and for each role in the List i call the business layer to load that object as suggested by you
Quote:
session.get(DeviceTypeRole.class, pk);


-> as expected update happens for each role in the list. But it doesnt overwrite or update the old list of DeviceType Roles in the Database


Any pointers/suggestions will be highly appreciated


Top
 Profile  
 
 Post subject: Criteria API with Composite Object
PostPosted: Wed Aug 15, 2007 7:55 pm 
Beginner
Beginner

Joined: Tue May 08, 2007 1:20 pm
Posts: 24
I have a Search screen for searching with variable number of conditions i.e. dynamically add "and condition" to where clause in the Query. Hence i am using Criteria API from Hibernate. The query works perfectly fine as criteria.list() correctly prints the no of records in the List. The problem occurs when i am trying to access the values in the Composite object having id values. It always return null value. Then i tried accessing value within the same pojo again it return the null
Here is the pojo

Code:
public class DeviceSummaryView implements java.io.Serializable {
// Fields

private DeviceSummaryViewId id;
private String tagNumber;
...
...
...
}
public class DeviceSummaryViewId implements java.io.Serializable {
// Fields

private Long deviceId;
private long interfaceId;
private Long ipId;
private Long hostNameId;

}

Any pointers/suggestions highly appreciated


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