Spring JPA阻止保存实体
我有以下数据库模式:Spring JPA阻止保存实体,spring,hibernate,spring-boot,jpa,spring-data-jpa,Spring,Hibernate,Spring Boot,Jpa,Spring Data Jpa,我有以下数据库模式: account -< account_role >- role 如何配置关系以防止插入 以下提到的课程: 角色 import javax.persistence.*; import static javax.persistence.EnumType.STRING; @Entity @Table(name = "ROLE") class Role { @Id @Column(name = "ROLE_NAME") @Enumerated(STRI
account -< account_role >- role
如何配置关系以防止插入
以下提到的课程:
角色
import javax.persistence.*;
import static javax.persistence.EnumType.STRING;
@Entity
@Table(name = "ROLE")
class Role {
@Id
@Column(name = "ROLE_NAME")
@Enumerated(STRING)
private RoleName role;
//getters, setters, constructors
}
及
账户
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
import static javax.persistence.FetchType.EAGER;
import static javax.persistence.GenerationType.SEQUENCE;
@Entity
@Table(name = "ACCOUNT")
public class Account {
@Id
@SequenceGenerator(allocationSize = 1, sequenceName = "ACCOUNT_PK_SEQ", name = "ACCOUNT_PK_SEQ")
@GeneratedValue(generator = "ACCOUNT_PK_SEQ", strategy = SEQUENCE)
@Column(name = "ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToMany(fetch = EAGER)
@JoinTable(
name = "ACCOUNT_ROLE",
joinColumns = @JoinColumn(name = "USERNAME", referencedColumnName = "USERNAME"),
inverseJoinColumns = @JoinColumn(name = "ROLE_NAME", referencedColumnName = "ROLE_NAME")
)
private Set<Role> roles = new HashSet<>();
//getters, setters, constructor
}
帐户
类的对象是根据请求自动创建的
可以找到完整的异常堆栈跟踪。问题是由
@Id
@Column(name = "ROLE_NAME")
@Enumerated(STRING)
JPA规范说:
2.1.4主键和实体标识
主键(或复合主键的字段或属性)应该是以下类型之一:任何Java基元类型;任何原始包装类型;java.lang.String;java.util.Date;java.sql.Date。但是,一般来说,主键中不应使用近似数字类型(例如浮点类型)。主键使用其他类型的实体将不可移植
因此,@Id和@Enumeration的组合似乎是不允许的,因为您将枚举用作Id
在当前代码中,您只能编写枚举角色名包含的元素数量相同的角色。这些是系统中预先定义的角色。
您应该在启动时这样做一次(或者确保它们存在)
添加注释
@Column(insertable=false, updatable=false)
对于Account.roles,这告诉JPA提供者在插入或更新帐户时不要插入或更新角色
这应该是可行的。请发布异常的完整堆栈跟踪,以及创建和持久化帐户的代码。确保您对帐户\角色。角色\名称没有唯一约束。@JBNizet,我有以下唯一约束:
ALTER TABLE account\角色添加约束帐户\角色\ UNQ unique(用户名,角色\名称)代码>,stacktrace已添加。您没有显示帐户角色的来源。如果他们应该存在,不要使用新角色(roleName)。从数据库中按ID获取角色(使用findOne()或getOne())是的,我使用的是new
,但正如您所看到的,role
(enum)是和ID
。从数据库获取角色有意义吗?Hibernate无法识别角色
字段ID?我几乎从不使用未生成的ID,因此我对这方面没有太多经验。我甚至不明白为什么Hibernate试图保存角色,因为您在关联上没有任何级联注释。但我的经验法则是,您应该避免像瘟疫这样的分离对象,如果数据库中存在一行,那么您应该从JPA获得相应的托管实体,而不是用一个(或几个不同的)分离对象来表示它。感谢您的响应和深入分析。我想它可以工作,但是我已经更改了DB设计,无法验证它:/
@Id
@Column(name = "ROLE_NAME")
@Enumerated(STRING)
@Column(insertable=false, updatable=false)