我有一个带有复合主键的实体。
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
.
如果我理解正确,你想使用
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);