【问题标题】:Springboot with JPA. Cannot Save to Auto Increment Field field in SQL Server. Null Error使用 JPA 的 Spring Boot。无法保存到 SQL Server 中的自动增量字段字段。空错误
【发布时间】:2018-04-21 18:24:56
【问题描述】:

我正在尝试使用带有 JPA 的 Spring Boot 来学习一些 API 开发,并且我在数据库中有这个表,其中 id 列指定为具有自动增量的主键。当我提交数据时,我不断收到此错误:

com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert the value NULL into column 'Id', table

在我的课堂上,我有这个作为 id。你可能会说为什么@Column(name='Id')。我在进行故障排除时开始添加它。当我从表中读取信息时,在进行一些更改之后,代码仍然可以正常工作。

package com.FUT.track.web.FUTtrackapplication.squads;

import javax.persistence.*;

@Entity
@Table(name="Squads")
public class Squad {

@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
@Column(name ="Id", nullable = false, unique = true)
public int id;
public String squadName;
public String squadDescription;
public String primaryFormation;


public Squad() {

}


public Squad(int id, String squadName, String squadDescription, String 

primaryFormation) {
    super();
    this.id = id;
    this.squadName = squadName;
    this.squadDescription = squadDescription;
    this.primaryFormation = primaryFormation;

}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getSquadName() {
    return squadName;
}

public void setSquadName(String squadName) {
    this.squadName = squadName;
}

public String getSquadDescription() {
    return squadDescription;
}

public void setSquadDescription(String squadDescription) {
    this.squadDescription = squadDescription;
}

public String getPrimaryFormation() {
    return primaryFormation;
}

public void setPrimaryFormation(String primaryFormation) {
    this.primaryFormation = primaryFormation;
}

}

不确定是否需要@GeneratedValue( strategy = GenerationType.IDENTITY),但不管有没有它,我仍然会遇到同样的错误。我正在提交除 id 之外的所有字段的数据。所有其他字段都可以存储空值,因此即使没有提交任何内容,我认为应该为新列生成 id。但由于某种原因,它不起作用。

也在我的应用程序属性文件中:

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

有什么建议吗?

【问题讨论】:

  • IDENTITY 表示您的数据库列是 IDENTITY 类型(任何 JPA 文档都会告诉您这一点),并将在 INSERT 上分配。当您持久化记录发布时,发出的 SQL 是什么。这是了解为什么会这样的第一步。也就是调试

标签: java sql-server api jpa spring-boot


【解决方案1】:

尝试做这样的事情:

import javax.persistence.*;

@Entity
@Table(name = "Squads")
public class Squad{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id", nullable = false, unique = true)
    public int id;

    @Column(name = "SquadName", nullable = false)
    private String squadName;

    @Column(name = "SquadDescription", nullable = false)
    private String squadDescription;

    @Column(name = "PrimaryFormation", nullable = false)
    private String primaryFormation;

    public Squad(){

    }

    public Squad(final String squadName, final String squadDescription, final String primaryFormation){

        this.squadName = squadName;
        this.squadDescription = squadDescription;
        this.primaryFormation = primaryFormation;
    }

    public int getId(){

        return id;
    }

    public void setId(final int id){

        this.id = id;
    }

    public String getSquadName(){

        return squadName;
    }

    public void setSquadName(final String squadName){

        this.squadName = squadName;
    }

    public String getSquadDescription(){

        return squadDescription;
    }

    public void setSquadDescription(final String squadDescription){

        this.squadDescription = squadDescription;
    }

    public String getPrimaryFormation(){

        return primaryFormation;
    }

    public void setPrimaryFormation(final String primaryFormation){

        this.primaryFormation = primaryFormation;
    }
}

请注意我是如何在构造函数中不包含“id”的。此外,我还为每个字段添加了列名。我假设您或您的 DBA 将希望使用驼峰式名称而不是下划线名称,因此在您的“application.properties”文件(或 yml ... 无论如何)中,将物理命名策略设置如下:

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

大多数使用 Microsoft SQL Server 的数据库开发人员和管理员更喜欢表名和列名的驼峰式大小写,而不是使用 JPA 和 Spring 假定为默认的下划线方法。例如,大多数情况下,在 Java/Spring 中,您希望表名是“MY_TABLE”,但在 SQL Server 中,您可能会有一个表名“MyTable”。由于这在 Spring 生态系统中是非标准的,因此您需要指定不同的命名策略。

【讨论】:

  • NoArgsConstructor AllArgsConstructor 注释的作用是什么,因为我已经在代码中拥有了这两个构造函数?至于命名约定,这只是我正在开发的用于学习目的的应用程序,但我仍然看不到您在哪里看到下划线。
  • 我没有看到下划线。大多数使用 Microsoft SQL Server 的数据库开发人员和管理员更喜欢表名和列名的驼峰式大小写,而不是使用 JPA 和 Spring 假定为默认的下划线方法。例如,在 Java/Spring 中,大多数情况下您期望的表名是“MY_TABLE”,但在 SQL Server 中,您可能会有一个表名“MyTable”。由于这在 Spring 生态系统中是非标准的,因此您需要指定不同的命名策略。
  • 至于注释,那些来自 Lombok,它会为你生成样板代码(构造函数、getter 和 setter 等),所以你不必这样做。不过,我可以看到这是如何使问题变得模糊的,因此我将删除它以进行澄清。
  • 哦,好的,谢谢。我从构造函数中删除了 Id 并为每个字段添加了 Column 注释,但仍然无法正常工作。根据我们的建议,我唯一没有改变的是属性文件中的策略。我的工作正常,可以从表中获取数据,所以我相信这很好,而不是归档映射的问题。我去了数据库并在表中插入了记录,它并不期望 Id 的值,因为它是自动生成的,所以真的令人难以置信为什么会发生这种情况。为了以防万一,我重新启动了我的 SQL 服务器,但仍然没有运气。
  • 顺便说一句,不知道为什么我不能用@添加你的用户名。当我保存时它会消失,以防万一你想知道。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2015-03-06
  • 1970-01-01
  • 2019-10-05
  • 2021-10-18
  • 2016-01-06
相关资源
最近更新 更多