Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring JPA阻止保存实体_Spring_Hibernate_Spring Boot_Jpa_Spring Data Jpa - Fatal编程技术网

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)