我正在使用 H2 数据库版本 2.2.224 和 Spring-Data-JPA 版本 3.3.3。我在“USERS”和“ROLES”表之间有多对多关系。
当我尝试将“Entity = USERS”保存到H2数据库时,出现以下错误:: org.h2.jdbc.JdbcSQLSyntaxErrorException:无法分配生成的列“PUBLIC.USERS.USER_ID_PK”。 SQL语句:插入用户(密码,登录名,user_id_pk)值(?,?,?)[90154-224]
在我看来,出现这个错误的原因是Spring JPA自己生成id并尝试将此id插入数据库本身,而H2想要自己生成id并将其插入表中。
如果我在“USERS”表中创建“user_id_pk”列,如下所示::“user_id_pk整数主键”并更改“Entity = USERS”中的GenerationType,则会出现各种错误。
如果我在“USERS”表中创建列“user_id_pk”,如下所示::role_id_pk整数GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY并更改“Entity = USERS”中的GenerationType,则会发生各种错误。
如果我在“USERS”表中创建列“user_id_pk”,如下所示::role_id_pk整数GENERATED ALWAYS AS IDENTITY PRIMARY KEY并更改“Entity = USERS”中的GenerationType,则会发生各种错误。
我创建了一个像这样的序列::
CREATE SEQUENCE USERS_SEQ START WITH 1 INCREMENT BY 50;
我的桌子::
CREATE TABLE PUBLIC.ROLES (
role_id_pk Integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
role VARCHAR
);
CREATE TABLE PUBLIC.USERS (
user_id_pk Integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
login VARCHAR,
password VARCHAR
);
我的实体::
@Entity
@Table(name = "users")
public class MyUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id_pk")
private Long id;
@Column(name = "login")
private String username;
@Column(name = "password")
private String password;
@ManyToMany
@JoinTable(name = "USERS_ROLES",
joinColumns = {@JoinColumn(name = "user_id_pk")},
inverseJoinColumns = {@JoinColumn(name = "role_id_pk")})
private List<Roles> listRoles;
我的实体::
@Entity
@Table(name = "roles")
public class Roles {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "role_id_pk")
private Long id;
@Enumerated(EnumType.STRING)
@Column(length = 20, name = "role")
private ERole name;
@ManyToMany(mappedBy="listRoles")
private List<MyUser> myUsersList;
您提到的第一个错误
Generated column "PUBLIC.USERS.USER_ID_PK" cannot be assigned
发生是因为您试图将值分配给生成的列(错误链接)。
关于错误
object references an unsaved transient instance - save the transient instance before flushing: Roles
的发生是因为您的实体 listRoles
中有集合 users
,并且该集合包含未存储在数据库中的项目。尝试在您的集合映射上添加 cascade=CascadeType.ALL
。
@ManyToMany(cascade = CascadeType.ALL)
private List<Roles> listRoles;
注意:实现双向多对多时,JPA 会创建一个链接两个实体的中间表。
下面是他们如何实现多对多关系的示例(页面是西班牙语,但代码很容易理解):https://www.oscarblancarteblog.com/2018/12/27/relaciones -很多很多/
我还为您留下了 Hibernate 为 Id 提供的不同类型的生成:https://www.baeldung.com/hibernate-identifiers