@OrderColumn生成更新主键的请求

时间:2011-05-26 09:00:02

标签: java hibernate jpa-2.0

我使用一个列表。该列表由复合主键组成,该主键也用于对列表进行排序。 问题是如果我删除列表中的元素(密钥化合物), 注释@OrderColumn生成更新主键的请求,并且成本会增加类型的异常:

[26-05-2011 10:34:18:835] WARN  org.hibernate.util.JDBCExceptionReporter  - SQL Error: 1062, SQLState: 23000  
[26-05-2011 10:34:18:835] ERROR org.hibernate.util.JDBCExceptionReporter  -Duplicate  entry '10-10' for key 'PRIMARY'  
[26-05-2011 10:34:18:835] ERROR org.hibernate.event.def.AbstractFlushingEventListener  - Could not synchronize database state with session org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update  

以下是映射的定义:

@ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "chapter_item", joinColumns = { @JoinColumn(name = "chapter_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "item_id", nullable = false, updatable = false) })
@OrderColumn(name="iorder")
public List<Item> getItems() {
    return items;
}

以下是我遇到问题的更新查询:

Hibernate: 
update
    chapter_item 
set
    item_id=? 
where
    chapter_id=? 
    and iorder=?  

我想知道这是否是一个已知错误,如果有人有解决方案?

2 个答案:

答案 0 :(得分:1)

关于@OrderColumn,可在http://docs.oracle.com/javaee/6/api/javax/persistence/OrderColumn.html

找到以下文档
  

指定用于维护a的持久顺序的列   名单。持久性提供程序负责维护   检索时和数据库中的订单。持久性提供程序是   负责在刷新到数据库时更新排序   反映影响列表的任何插入,删除或重新排序。

因此我们看到持久性提供程序即hibernate负责更新名为iorder的列。还有人说:

  

OrderColumn注释在OneToMany或ManyToMany上指定   关系或元素集合。 OrderColumn注释   在引用该关系的关系一侧指定   要订购的集合。订单列不可见   部分实体或可嵌入类的状态。

请注意以下句子:

  

订单栏不可见为实体状态的一部分或   可嵌入的课程。

因此,我建议您考虑不要为iorder选择@OrderColumn列,因为它是composite key的一部分,而hibernate肯定会在您删除或更新时更新此值在列表中插入一个元素(List<Item>)。

希望,这有帮助。

答案 1 :(得分:0)

也许一个选项可以更改订单注释并使用:

@ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "chapter_item", joinColumns = { @JoinColumn(name =     "chapter_id", nullable = false, updatable = false) }, inverseJoinColumns =  {@JoinColumn(name = "item_id", nullable = false, updatable = false) })
@org.hibernate.annotations.Sort(type = SortType.COMPARATOR, comparator = ItemComparator)
public List<Item> getItems() {
return items;
}

closure

检查性能解决方案,因为对于大量数据而言可能太慢,如果您可以共享,那么可能的解决方案很有用