java - 删除元素时使用 JoinTable 和 OrderColumn 的 Hibernate 单向 OneToMany 映射中的约束违规

标签 java hibernate jpa jpa-2.0 one-to-many

从如上所述映射的列表中删除元素时遇到问题。这是映射:

@Entity
@Table( name = "foo")
class Foo {

    private List bars;

    @OneToMany
    @OrderColumn( name = "order_index" )
    @JoinTable( name = "foo_bar_map", joinColumns = @JoinColumn( name = "foo_id" ), inverseJoinColumns =  @JoinColumn( name = "bar_id" ) )
    @Fetch( FetchMode.SUBSELECT )
    public List getBars() {
        return bars;
    }
}

插入 Bar 实例并保存 Foo 工作正常,但是当我从列表中删除一个元素并再次保存时,违反了映射表中 bar_id 的唯一约束。下面的 SQL 语句是由 hibernate 发出的,这些看起来很奇怪:

LOG:  execute : delete from foo_bar_map where foo_id=$1 and order_index=$2
DETAIL:  parameters: $1 = '4', $2 = '6'
LOG:  execute S_5: update foo_bar_map set bar_id=$1 where foo_id=$2 and order_index=$3
DETAIL:  parameters: $1 = '88', $2 = '4', $3 = '0'
ERROR:  duplicate key value violates unique constraint "foo_bar_map_bar_id_key"

鉴于 Hibernate 生成的语句(列表中有五个项目,我删除了第一个,Hibernate 删除了具有 LAST 索引的映射行并尝试更新其余的,从第一个)。

上面的映射有什么问题?

最佳答案

您的映射是完全有效的,并且可以作为 JPA 2.0 实现与 EclipseLink 一起使用(当然没有 Fetch 注释),但确实与 Hibernate 一起失败。

这是 Hibernate 的 DDL:

create table foo_bar_map (foo_id bigint not null, bar_id bigint not null, order_index integer not null, primary key (foo_id, order_index), unique (bar_id))
alter table foo_bar_map add constraint FK14F1CB7FA042E82 foreign key (bar_id) references Bar4022509
alter table foo_bar_map add constraint FK14F1CB7B6DBCCDC foreign key (foo_id) references Foo4022509

假设 Foo#1 包含一个包含 Bar#1Bar#2Bar#3,连接表包含:

foo_id | bar_id | order_index
     1 |      1 |           1
     1 |      2 |           2
     1 |      3 |           3

当删除时,比如列表中的第一项,Hibernate 首先从连接表中删除最后一行(WTF?):

foo_id | bar_id | order_index
     1 |      1 |           1
     1 |      2 |           2

然后尝试更新连接表中的bar_id列而不是order_index(WTF!?)以反射(reflect)“新"列表中项目的排序。首先(示意图):

foo_id | bar_id | order_index
     1 |      2 |           1
     1 |      2 |           2

下一步将导致:

foo_id | bar_id | order_index
     1 |      2 |           1
     1 |      3 |           2

显然,由于 bar_id 上的 unique 约束,这种方法听起来不对并且不起作用。更一般地说,为什么 Hibernate 搞砸了 bar_id 而不是更新 order_index 列?

我认为这是一个 Hibernate 错误(报告为 HHH-5694 ,现在请参阅 HHH-1268)。

关于java - 删除元素时使用 JoinTable 和 OrderColumn 的 Hibernate 单向 OneToMany 映射中的约束违规,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4022509/

相关文章:

mysql - Hibernate session.beginTransaction()调用和Mysql Start Transaction

java - 如何将自定义对象 ID 注入(inject) JPA 实体

java - 我们可以在属性文件中设置JTA数据源名称吗

java - JPA find() 有效,坚持无异常无结果,删除显示查询并抛出删除分离实例异常

java - 使用 Unirest JAVA 进行身份验证

java - Hibernate - 如何使用外键

java - 离开和返回 Activity 后使用计时器 onTick 更新 TextView

java - 在 hibernate 中延迟加载对象

java - 是否有必要从neo4j社区版迁移到企业版以及关于在neo4j中创建新数据库的查询

java - 同步的 java 代码执行速度比非同步代码快几倍