首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

求教Hibernate级联操作自动更新的难点

2011-12-10 
求教Hibernate级联操作自动更新的难题!很头疼,搞到凌晨三点了还没解决,请大家帮我看看,至少让我这8个小时

求教Hibernate级联操作自动更新的难题!
很头疼,搞到凌晨三点了还没解决,请大家帮我看看,至少让我这8个小时死得其所。

表:
product.java
private Set<ProductAttributeValue>productAttributeValues= new HashSet<ProductAttributeValue>(0) ;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "product")
public Set<ProductAttributeValue> getProductAttributeValues()
{
return this.productAttributeValues ;
}

productAttributeValue.java //产品属性的值private Productproduct ;
private CategoryAttributecategoryAttribute ;
private StringattributeValue ;

两者是一对多的关系。

现在操作product,在productAction中save的时候,出现这样的问题:

如果是新添加的product:
//因为要对应到前台若干个属性,所以这里采用List方便映射
private List<ProductAttributeValue>productAttributeValue ;
//productAttributeValue对应到前台若干个input,他们表示产品的多个属性
for (int i = 0; i < productAttributeValue.size(); i++)
{
  productAttributeValue.get(i).setProduct(entity) ; //如果是添加产品,则必须在此设置product的id
}
//转换list为set
Set<ProductAttributeValue> productAttributeValues = new HashSet<ProductAttributeValue>(productAttributeValue) ;
entity.setProductAttributeValues(productAttributeValues) ;

OK,到目前为止,一切正常,产品能够添加成功,属性也因为hibernate的级联自动添加了。

问题在于:
如果我现在添加了一个产品,只有一个属性。那么我再修改这个产品的时候,修改了产品属性,我们可爱的hibernate级联操作竟然不是update而是insert了一个新的属性,sql的痕迹如下:
Hibernate: 
  insert 
  into
  xunma.product_attribute_value
  (attribute_value, attribute_id, product_id) 
  values
  (?, ?, ?)
Hibernate: 
  update
  xunma.product 
  set
  category_id=?,
  create_time=?,
  descript=?,
  name=?,
  read_count=?,
  trade_id=? 
  where
  id=?

不仅insert了,还update。莫明其妙啊。


然后我一路追凶,发现如果在prepareModel()中,对productAttributeValue的值进行更改,则可以避免这种情况:
productAttributeValue = new ArrayList<ProductAttributeValue>(entity.getProductAttributeValues()) ;
在prepareModel中,我让productAttributeValue(这个东东对应到前台jsp中的若干个属性input)的值设置为从数据库中获取之前的属性的值。然后再save()的时候:
Set<ProductAttributeValue> productAttributeValues = new HashSet<ProductAttributeValue>(productAttributeValue) ;
entity.setProductAttributeValues(productAttributeValues) ;
这样,就不会出现修改属性的时候不是update而是insert了。我不知道为什么。但事实是这样,这是疑问一

然而,随之而来的问题出现了:
由于prepareModel()中我调整了productAttributeValue的值,比如之前productAttributeValue长度为3,表示有3个属性,而我当前修改了这个产品的分类,因为不同的分类拥有不同的属性,新的分类可能之后2个属性。这样就出问题了:

问题1:save之后,product以前的3个属性,其中有2个修改为新的属性了,而还有多的1个属性还存在,它这是不应该属于这个世界。

问题2:如果当前有2个属性,然后修改分类之后有了3个属性,就会出现这样的错误:
identifier of an instance of com.xunma.entity.product.CategoryAttribute was altered from 9 to 10;
网上说这个错误和id的类型有关,事实上我这里的所有主键id都是同一个类型和策略。所以排除这个可能。

小弟对hibernate和struts2了解不够深入,还请大家帮我看看,这些原因到底是什么造成的,该如何解决。不慎感激!

[解决办法]
对hibernate也不是很熟,帮顶了
[解决办法]
问题1:entity里的多余ProductAttributeValue可以设成NULL,只要对应的值改变了,那么就会更新了
问题2:这种错误,往往都是由于数据库中的类型和 javaBean 中类型不匹配产生的
[解决办法]
我怀疑是你修改ProductAttributeValue的代码有问题。你只贴出了添加新属性的代码,把修改的代码也放上来看看。
[解决办法]
如果我现在添加了一个产品,只有一个属性。那么我再修改这个产品的时候,修改了产品属性,我们可爱的hibernate级联操作竟然不是update而是insert了一个新的属性

只能是当保存product的时候,productAttributeValues存在数据,所以执行了update和insert

identifier of an instance of com.xunma.entity.product.CategoryAttribute was altered from 9 to 10; 


类型需要检查,比如数据库是bigint而你的类型是int,包括那个字段的类型都检查一下
[解决办法]

探讨
如果我现在添加了一个产品,只有一个属性。那么我再修改这个产品的时候,修改了产品属性,我们可爱的hibernate级联操作竟然不是update而是insert了一个新的属性

只能是当保存product的时候,productAttributeValues存在数据,所以执行了update和insert

identifier of an instance of com.xunma.entity.product.CategoryAttribute was altered from 9 to 10;
类型需要检查,比如数据库是bigint而你的类型是int,包括那个…

[解决办法]
呵呵,记得呀

第一个问题,就是productAttributeValues肯定存在数据了,所以就执行了insert

第二个问题是前台是list,后台莫不如直接改成collection了,呵呵,
[解决办法]
其实,如果你的数据已经存在的话,你要是想更新而且使用的HIEBERTNATE的话,就要先把这条数据查询出来后在使用UPdate的方法,不然就会执行一个insert语句。

热点排行