-->
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: unnecessary update action when save object
PostPosted: Tue Feb 27, 2007 12:55 pm 
Beginner
Beginner

Joined: Wed Aug 27, 2003 3:46 am
Posts: 34
Location: Taiwan
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: hibernate-3.2

This is my scenario :

Item and Category are many-to-many relation , the owning side is Item.
Item and Image are one-to-many relation , Image(DELETE_ORPHAN) is dependent on Item :
Code:
In Item.java :
  @OneToMany( fetch=FetchType.EAGER )
  @Cascade(value = {CascadeType.SAVE_UPDATE , CascadeType.DELETE_ORPHAN} )
  @JoinColumn(name="ItemID")
  @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  private Set<Image>   images   = new HashSet<Image>();



When I create a new Item , add Images , add Categories , and save it (using getHibernateTemplate().save(newItem) ) ; the SQL dump is as following :

Code:
Hibernate: insert into Item (uuid, ....) values (?, ....)
Hibernate: insert into Image (data, size, ....) values (?, ?,...)
Hibernate: insert into Image (data, size, ....) values (?, ?,...)
Hibernate: insert into Image (data, size, ....) values (?, ?,...)
Hibernate: insert into Image (data, size, ....) values (?, ?,...)
Hibernate: insert into Item_Category (ItemID, CategoryID) values (?, ?)
Hibernate: update Image set ItemID=? where ID=?
Hibernate: update Image set ItemID=? where ID=?
Hibernate: update Image set ItemID=? where ID=?
Hibernate: update Image set ItemID=? where ID=?


I noticed that hibernate does redundant 'update' actions.
It seems that adding category to item makes hibernate think the item is updated , but it does not related to item's Image set...
How to avoid the redundant update actions ?

I tried to change the CascadeType to :
@Cascade(value = {CascadeType.PERSIST , CascadeType.DELETE_ORPHAN} )
But it throws TransientObjectException :
Code:
Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: foo.bar.Image


Maybe getHibernateTemplate().persist(newItem) can solve the problem , but persist doesn't return the generated identifier.

What should I do ?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 28, 2007 12:20 am 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
Hi smallufo,

try Bidirectional mapping with inverse =true in set .That will reduce your extra update

_________________
Dharmendra Pandey


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 28, 2007 1:36 am 
Beginner
Beginner

Joined: Wed Aug 27, 2003 3:46 am
Posts: 34
Location: Taiwan
Quote:
try Bidirectional mapping with inverse =true in set .That will reduce your extra update


Hi , but I don't want Item and Image are bi-directional.
Any other suggestions ?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 28, 2007 2:17 am 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
Hi smallufo,

you will have to choose one of the either bi-directional or extra update. One quick hack is that use inverse="true" you should have foreign key and in child use insert false update false for that column. Might work .

_________________
Dharmendra Pandey


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 28, 2007 4:24 pm 
Beginner
Beginner

Joined: Wed Aug 27, 2003 3:46 am
Posts: 34
Location: Taiwan
dharmendra.pandey wrote:
Hi smallufo,

you will have to choose one of the either bi-directional or extra update. One quick hack is that use inverse="true" you should have foreign key and in child use insert false update false for that column. Might work .


Thank you , but after I modify the relationship to bi-directional , there are still redundant update actions :

Code:
In Item.java :
  @OneToMany(fetch=FetchType.EAGER)
  @JoinColumn(name="ItemID")
  @Cascade(value = {CascadeType.SAVE_UPDATE , CascadeType.DELETE_ORPHAN} )
  @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  private Set<Image>   images   = new HashSet<Image>();


Code:
In Image.java :
  @ManyToOne()
  @JoinColumn(name="ItemID" , insertable=false, updatable=false)
  protected Item item;


Why ? anything missed ?
Does it related to the missing inverse="true" ? I don't know where to add ...
I tried to add to here :
Code:
In Item.java :
@OneToMany(fetch=FetchType.EAGER , mappedBy="item")


But I got an AnnotationException: mappedBy reference an unknown target entity property: foobar.Image.item in foobar.Item.images


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 28, 2007 5:07 pm 
Beginner
Beginner

Joined: Wed Aug 27, 2003 3:46 am
Posts: 34
Location: Taiwan
I found the problem .

In fact , the Image class is abstract , I have to copy this
Code:
  @ManyToOne()
  @JoinColumn(name="ItemID" , insertable=false, updatable=false)
  protected Item item;


to classes that inherit it.

And this solves the duplicated UPDATE actions problem.

This raises another question : why should I copy the item field to its (Image's) descendants ... ? It should be inheritanced...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 28, 2007 11:59 pm 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
Hi smallufo,


Have a reference


http://simoes.org/docs/hibernate-2.1/155.html

I don't know how to do by annotation

_________________
Dharmendra Pandey


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.