【问题标题】:@OrderColumn generates a request to update the primary key@OrderColumn 生成更新主键的请求
【发布时间】:2011-09-02 10:10:53
【问题描述】:

我使用列表。该列表由一个复合主键组成,该主键也用于对列表进行排序。 问题是如果我删除列表中的一个元素(关键化合物), 注解@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=?  

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

【问题讨论】:

  • 1) 您是否在 Item 类中创建了 equals & hashCode? 2)它是2路关联吗? (从你的班级到项目)和 3)请包括你用来删除项目的代码。
  • 你能提供给我们你的章节和项目的实现吗?
  • 你不能使用 cascade=CascadeType.ALL
  • 错误表明您的 UPDATE 查询导致数据库中不允许出现重复的主键。如果更新将现有主键设置为另一条记录,或者如果更新条件适用于超过 1 条记录。
  • 我认为这已经在这里得到了回答:stackoverflow.com/questions/4022509/… 这不是完全相同的映射,但 Hibernate 的问题似乎是一样的。

标签: java hibernate jpa-2.0


【解决方案1】:

关于@OrderColumn,以下文档位于http://docs.oracle.com/javaee/6/api/javax/persistence/OrderColumn.html

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

所以我们看到持久化提供者,即hibernate负责更新名为iorder的列。也有人说:

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

请注意下面的句子:

订单列作为实体状态的一部分不可见,或者 可嵌入类。

所以,我建议您不要为@OrderColumn 选择列iorder,因为它是您的composite key 的一部分,并且当您在列表中删除或插入元素时,休眠肯定会更新此值( List&lt;Item&gt;)。

希望,这会有所帮助。

【讨论】:

    【解决方案2】:

    也许一种选择是更改订单注释并使用:

    @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;
    }
    

    https://dzone.com/articles/sorting-collections-hibernate

    检查性能解决方案,因为对于大量数据来说可能太慢了,如果你能分享一个可能的解决方案,那就太好了

    【讨论】:

      猜你喜欢
      • 2022-08-17
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 2013-08-29
      相关资源
      最近更新 更多