无法使用带有 InhertanceType.JOINED 的 Spring JPA 持久化实体

Posted

技术标签:

【中文标题】无法使用带有 InhertanceType.JOINED 的 Spring JPA 持久化实体【英文标题】:Cannot persist entity with Spring JPA with InhertanceType.JOINED 【发布时间】:2020-02-21 22:08:27 【问题描述】:

我有以下 JPA 实体类。还有另一个扩展 Project 的实体 OptProject。我正在使用 InheritanceType.JOINED

public class Project 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false)
    private Long id;

    @Basic
    @Column(name = "NAME", nullable = false, length = 150)
    private String name;

    @Basic
    @Column(name = "DESCRIPTION", nullable = false, length = 500)
    private String description;

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getDescription() 
        return description;
    

    public void setDescription(String description) 
        this.description = description;
    


@Entity
@Table( name = "opt_project")
public class OptProject extends Project 

    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
    private List<Case> cases = new ArrayList<>();

    public OptProject() 

    public OptProject(String name, String description) 
        super(name, description);
            

OptProject 实体的 JPA 存储库如下

@Repository
public interface OptProjectRepository extends CrudRepository<OptProject, Long> 


当我创建一个 OptProject 并尝试保存它时,我收到以下错误消息。这对我来说是零意义,因为我使用 @GeneratedValue(strategy = GenerationType.IDENTITY) 为 SQL 服务器生成 ID 主键。

    OptProject optProject = new OptProject("name", "description");
    OptProject savedProject = optProjectRepo.save(optProject);

com.microsoft.sqlserver.jdbc.SQLServerException:当 IDENTITY_INSERT 设置为 OFF 时,无法在表“optimization_project”中插入标识列的显式值。

使用以下 sn-ps 将 hibernate 日志记录转为调试后

logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql=trace

这些是休眠 SQL 日志:

DEBUG org.hibernate.SQL - insert into dbo.project (name, description) values (?, ?)
TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [name]
TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [description]
DEBUG org.hibernate.SQL - insert into opt_project (id) values (?)
TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [BIGINT] - [11]
WARN  o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 544, SQLState: S0001
ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Cannot insert explicit value for identity column in table 'opt_project' when IDENTITY_INSERT is set to OFF.

将数据插入到基类 Project 表中的第一条 SQL 语句是正确的。但是将数据插入到子类 OptProject 的第二个表的 SQL 语句是问题所在。它是手动添加值为 11 的 ID,而不是让 db 生成它,可能是因为这里只有 ID 字段。我不确定这里发生了什么。

【问题讨论】:

***.com/questions/452238/… 的可能重复项 @EduardoEljaiek,它不是重复的,因为 ID 生成器策略是 GenerationType.IDENTITY。这意味着我没有为 ID 传递显式值,并且 db 应该在执行插入时为我生成一个。 【参考方案1】:

它是手动添加值为 11 的 ID,而不是让 db 生成它,可能是因为这里只有 ID 字段。我不确定这里发生了什么。

您正在使用联合继承类型。依赖实体必须与父实体具有相同的 PK,否则它们将如何加入?唯一会发生的方法是在插入时手动设置依赖实体的 ID 值。因此,您需要更改 opt_project 表中的列定义,使其不是身份列。

【讨论】:

你是绝对正确的,我在我的表创建脚本中为 opt_project 表 [opt_project_id] [bigint] IDENTITY(1,1) NOT NULL 添加了 IDENTITY 说明符。这肯定会在父类中定义的 IDENTITY 之间产生冲突。删除它解决了这个问题。谢谢。

以上是关于无法使用带有 InhertanceType.JOINED 的 Spring JPA 持久化实体的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 AFNetworking 发布带有数组的字典

无法使用带有自定义单元的 BaseButtonBarPagerTabStripViewController 连接 XLPagertabStrip 插座

我无法使用带有 jquery 的 Handsontable 加载数据

带有 $cond 的 MongoDB 聚合管道 $addFields - 无法使用变量

无法使用“角色”包向带有流星的用户添加角色

无法在带有 Kotlin 的 Android 中使用 Autodispose