Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Hibernate Spring,CompositeKey Update failure

 
sudhakar Tadepalli
Ranch Hand
Posts: 130
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I am running a test web application using a Spring,Hibernate,Struts. I have a table without any PrimaryKeys. But the The whole record is Unique.
Table has 3 records like this.

4545 9595 1234 James Yes
4545 9595 1234 John NoValue2
4545 9595 1234 Bobby NoValue2

I have fetched the record and displayed in JSP and selected middle record for edit. Then I have updated all fileds except first one(4545)

Ex: 4545 9595 1234 John NoValue2
Now it is : 4545 8888 7777 Mitch Developer

I am setting the values to a "Data" object and passing it method in "HibernateSupport" class called "getHibernateTemplate().update(data)getHibernateTemplate().update(data);;"

It does not throw exception and it did not updated the record.

I tried with getHibernateTemplate().saveOrUpdate(data) also. But no luck.

Here is my Mapping file

<hibernate-mapping package="com.test.model">
<class name="Data" table="apenodeproperties">
<composite-id >
<key-property name="sceneid" column="SCENEID" type="long"></key-property>
<key-property name="personid" column="PERSONID" type="long"></key-property>
<key-property name="nodeid" column="NODEID" type="long"></key-property>
<key-property name="name" column="NAME" type="java.lang.String"></key-property>
<key-property name="value" column="VALUE" type="java.lang.String"></key-property>
</composite-id>
</class>
</hibernate-mapping>

The question is : How this support class know which record I updated ?.
How to resolve this issue?.
I thout to pass actual values to the DAOHelper and search the record based on old values then update that object with new values but...here I am making two calls to DB.

Ant thouts will be appreciated.

Thanks
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

How this support class know which record I updated ?.

You can't update a record which has a composite key comprising all fields in the table. The reason is Hibernate assumes your data should behave as relational data is designed to behave. One of the rules of relational data is the key identifies the record. If your composite key comprises every field in the table, you will never be able to update the data, only insert new data. Why? Since the key identifies the record, and the key is every field in a record, then the record's identifier == the record itself. Any change to the identifier means you are dealing with a new record.

That being said, you should be able to call session.save(obj) with an object which has a composite key (you will never be able to use session.update() for the reason above).


How to resolve this issue?.

The easiest (and best) way is to give the table a proper surrogate key and use that as the identifier. Is there a reason why you have not done this? Is this a legacy data model?
 
sudhakar Tadepalli
Ranch Hand
Posts: 130
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thaks Paul, Can you believe this table is in Production ?. What is surrogateKey ? If i assign the surrogateKey to the table what are the changes to my Mapping(hbm.xml) file ?
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Can you believe this table is in Production?

Eek! Fire your DBA!

A surrogate key is an arbritary value assigned to a record to act as a Primary Key. It is not part of the data you are describing, it is only there to identify it. So with your example you would add an id field to your
apenodeproperties table, create a Primary Key constraint on that column and use one of Hibernate's key generation strategies to populate it. Then you can change your complex composite-id element into simple properties elements and refer to the object via the surrogate key. Make sense?
 
Sonny Gill
Ranch Hand
Posts: 1211
IntelliJ IDE Mac
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another possible option, if you are not in a position to alter the table definition, is to use some database specific row identifier.

For example, in Oracle you can use rowid to identifiy a record.

I am not sure what version of Hibernate supports what database specific identifiers, but I remember reading that support for Oracle rowid was expected in one of the newer Hibernate releases.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic