复合主键,使用@IdClass - 列'id'不能为空

问题描述 投票:0回答:1

我有一个带有复合主键的实体。

id - version
将是主键。

id 版本 A 列
1 1 一些数据
1 2 一些数据
2 1 一些数据
2 2 一些数据

我正在使用

@IdClass
来处理复合主键。

@Entity
@IdClass(MyKey.class)
public class YourEntity {
   @Id
   private int id;
   @Id
   private int version;
}


public class MyKey implements Serializable {
   private int id;
   private int version;
}

当我想插入新行到表中时,换句话说,我想添加新的

id
,它抱怨
Column 'id' cannot be null

我不希望

id
成为
null
。根据我的表格,当我插入一个新行时,应该添加新的
id
,其值为
3
.

spring hibernate jpa orm composite-primary-key
1个回答
0
投票

如果我理解正确,你想使用

AUTO_INCREMENT
作为
id
列。您应该能够将
@GeneratedValue(strategy = GenerationType.IDENTITY)
用于实体的
id
字段。但是,不幸的是,由于HHH-9662,你不能这样做。这不是一个严重的错误,因为它没有违反 JPA 规范。

作为解决方法,您可以使用 Vlad Mihalcea 的文章中描述的方法。

假设你有下表:

create table test_my_entity (
    id int not null AUTO_INCREMENT,
    version int,
    name  varchar(50),

    primary key (id, version)
);

您可以使用以下映射:

import org.hibernate.annotations.SQLInsert;
import javax.persistence.EmbeddedId;
// ...

@Entity
@Table(name = "test_my_entity")
@SQLInsert(sql = "insert into test_my_entity(name, id, version) values (?, ?, ?)")
public class MyEntity {

    @EmbeddedId
    private MyEntityPk pk;

    @Column(name = "name")
    private String name;

    // getters and setters ...
}


@Embeddable
public class MyEntityPk implements Serializable {
    private int id;
    private int version;

    public MyEntityPk() {
    }

    public MyEntityPk(int version) {
        this.version = version;
    }

    public MyEntityPk(int id, int version) {
        this.id = id;
        this.version = version;
    }

    public int getId() {
        return id;
    }

    public int getVersion() {
        return version;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyEntityPk that = (MyEntityPk) o;
        return version == that.version && id == that.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, version);
    }

}

以及如何插入新行的示例:

MyEntity myEntity = new MyEntity();
myEntity.setPk(new MyEntityPk(5));
myEntity.setName("Yulia");
entityManager.persist(myEntity);
© www.soinside.com 2019 - 2024. All rights reserved.