无法添加表行,因为“当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'Users' 中插入标识列的显式值”错误

Posted

技术标签:

【中文标题】无法添加表行,因为“当 IDENTITY_INSERT 设置为 OFF 时,无法在表 \'Users\' 中插入标识列的显式值”错误【英文标题】:Cannot add a table row because of "Cannot insert explicit value for identity column in table 'Users' when IDENTITY_INSERT is set to OFF" error无法添加表行,因为“当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'Users' 中插入标识列的显式值”错误 【发布时间】:2020-06-19 21:21:37 【问题描述】:

我尝试使用 Spring boot 和 JPA 将用户保存到数据库,但由于此错误,它对我不起作用。

com.microsoft.sqlserver.jdbc.SQLServerException: 
Cannot insert explicit value for identity column in table 'Users'
when IDENTITY_INSERT is set to OFF.

错误 很清楚,所以我尝试更改身份 在我的数据库中插入成功,但错误仍然发生。在那个问题中奇怪的第二件事是我没有尝试将特定值作为 id 放入我的数据库。 这是负责保存数据的确切行:

userService.save(new User("wikimmax","test","testmail@op.pl","test", Arrays.asList(new Role("ROLE_USER"))));

还有我的用户类

import javax.persistence.*;
import java.util.Collection;

@Entity
@Table(name = "Users",uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class User 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    private String firstName;
    private String lastName;
    private String email;
    private String password;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(
            name = "users_roles",
            joinColumns = @JoinColumn(
                    name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(
                    name = "role_id", referencedColumnName = "id"))
    private Collection<Role> roles;

    public User() 
    

    public User(String firstName, String lastName, String email, String password) 
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
    

    public User(String firstName, String lastName, String email, String password, Collection<Role> roles) 
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
        this.roles = roles;
    

    public Long getId() 
        return id;
    

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

    public String getFirstName() 
        return firstName;
    

    public void setFirstName(String firstName) 
        this.firstName = firstName;
    

    public String getLastName() 
        return lastName;
    

    public void setLastName(String lastName) 
        this.lastName = lastName;
    

    public String getEmail() 
        return email;
    

    public void setEmail(String email) 
        this.email = email;
    

    public String getPassword() 
        return password;
    

    public void setPassword(String password) 
        this.password = password;
    

    public Collection<Role> getRoles() 
        return roles;
    

    public void setRoles(Collection<Role> roles) 
        this.roles = roles;
    

    @Override
    public String toString() 

        return "User" +
                "id=" + id +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", password='" + "*********" + '\'' +
                ", roles=" + roles +
                '';
    


有我的表属性:

非常感谢任何想法

更新我设法打印了由 hibernate 生成的 SQL 查询,它看起来像这样:

    insert 
    into
        Users
        (email, firstName, lastName, password, id) 
    values
        (?, ?, ?, ?, ?)

【问题讨论】:

为什么不允许 SQL Server 管理标识列并告诉 JPA 改用 @GeneratedValue(strategy=GenerationType.IDENTITY) 很遗憾,您需要任何其他信息也无济于事吗? 【参考方案1】:

请编辑问题并添加插入语句。

您不能在标识列中插入任何数据,因为这些列由SQL引擎自动填充,在Insert语句中删除id列并重试。

设置身份,但这不是一个好主意。 允许将显式值插入到表的标识列中。

SET IDENTITY_INSERT Users ON

例如:

USE AdventureWorks2012;  
GO  
-- Create tool table.  
CREATE TABLE dbo.Tool(  
   ID INT IDENTITY NOT NULL PRIMARY KEY,   
   Name VARCHAR(40) NOT NULL  
);  
GO  
-- Inserting values into products table.  
INSERT INTO dbo.Tool(Name)   
VALUES ('Screwdriver')  
        , ('Hammer')  
        , ('Saw')  
        , ('Shovel');  
GO  

-- Create a gap in the identity values.  
DELETE dbo.Tool  
WHERE Name = 'Saw';  
GO  

SELECT *   
FROM dbo.Tool;  
GO  

-- Try to insert an explicit ID value of 3;  
-- should return an error:
-- An explicit value for the identity column in table 'AdventureWorks2012.dbo.Tool' can only be specified when a column list is used and IDENTITY_INSERT is ON.
INSERT INTO dbo.Tool (ID, Name) VALUES (3, 'Garden shovel');  
GO  
-- SET IDENTITY_INSERT to ON.  
SET IDENTITY_INSERT dbo.Tool ON;  
GO  

-- Try to insert an explicit ID value of 3.  
INSERT INTO dbo.Tool (ID, Name) VALUES (3, 'Garden shovel');  
GO  

SELECT *   
FROM dbo.Tool;  
GO  
-- Drop products table.  
DROP TABLE dbo.Tool;  
GO

【讨论】:

这样做很好,但是 spring 在后台自行执行 SQL 查询,你知道我可以如何手动更改吗? 您也可以运行SET IDENTITY_INSERT Users ON。这将允许您在列 Users.Id 中显式插入值,这可能是一个非常糟糕的主意,具体取决于首先将其设置为身份的确切原因。要恢复当前行为,只需运行 SET IDENTITY_INSERT Users OFF

以上是关于无法添加表行,因为“当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'Users' 中插入标识列的显式值”错误的主要内容,如果未能解决你的问题,请参考以下文章

动态切换表行的可见性 - bootstrap-vue

在 vueJS 2 中具有分页但无法呈现的 element-ui 表行的背景颜色

在跨表行中添加图像以相对于其他非跨行行保持居中

子表行的休眠批处理

Swift:以编程方式重新排序表行

JQuery追加到表行的末尾而不是Tbody?