org.hsqldb.HsqlException:计数的行数存在差异

问题描述

我正在尝试使用一个不安全的应用程序 (Insecure Bank),并且我正在尝试将它移植到更安全的个人项目中。

我在将数据库内容插入内存中的数据库时遇到问题。有这两个表:

create table cashaccount (
    id int,number varchar(80) not null,username varchar(80)  not null,availablebalance double precision,description varchar(80)  not null,constraint pk_cashaccount primary key (id)
);

create table creditaccount(
    id int,cashaccountid int,constraint pk_creditaccount primary key (id)
);

而一些预期插入的值是:

INSERT INTO cashaccount VALUES (1,'10669803404133150948','ray',3424.32,'Checking Account');
INSERT INTO cashaccount VALUES (2,'00948343154448310446','joby',2479.13,'Checking Account');
INSERT INTO cashaccount VALUES (3,'51846636433522240425','john',2134.10,'Checking Account');

INSERT INTO creditaccount VALUES (1,'4024 0071 5848 6471','Visa Gold',1);
INSERT INTO creditaccount VALUES (2,'4929 1294 1877 8806',2);
INSERT INTO creditaccount VALUES (3,'5521 0508 7181 1232','MasterCard',3);

但是当 Hibernate 尝试在应用程序开始时插入值时(我使用 import.sql 文件夹中的 resources 文件),我收到此错误:>

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "INSERT INTO creditaccount VALUES (1,1)" via JDBC Statement
...
Caused by: java.sql.sqlSyntaxErrorException: discrepancy in the number of rows counted
...
Caused by: org.hsqldb.HsqlException: discrepancy in the number of rows counted
...

我已经像这样映射了实体:

@Entity
@Table(name = "cashaccount")
public class CashAccount {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @NotEmpty
    @Size(max = 80)
    private String number;

    @NotEmpty
    @Size(min = 2,max = 80)
    private String username;

    @NotNull
    private double availablebalance;

    @NotEmpty
    @Size(min = 10,max = 80)
    private String description;

    @OnetoMany(mappedBy="cashAccount",cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private Set<Creditaccount> creditaccounts = new HashSet<>();

    public CashAccount() {
    }

    public CashAccount(@NotEmpty @Size(max = 80) String number,@NotEmpty @Size(min = 2,max = 80) String username,@NotNull double availablebalance,@NotEmpty @Size(min = 10,max = 80) String description) {
        this.number = number;
        this.username = username;
        this.availablebalance= availablebalance;
        this.description = description;
    }
    
    // Setters and getters

@Entity
@Table(name = "creditaccount")
public class Creditaccount {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @NotEmpty
    @Size(max = 80)
    private String number;

    @NotEmpty
    @Size(min = 2,max = 80)
    private String username;

    @NotEmpty
    @Size(min = 10,max = 80)
    private String description;

    @NotNull
    private double availablebalance;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id",insertable = false,updatable = false)
    private CashAccount cashAccount;

    public Creditaccount() {
    }

    public Creditaccount(@NotEmpty @Size(max = 80) String number,max = 80) String description,@NotNull CashAccount cashAccount) {
        this.number = number;
        this.username = username;
        this.description = description;
        this.availablebalance = availablebalance;
        this.cashAccount = cashAccount;
    }
    
    // Setters and getters

但我不知道错误在哪里或我做错了什么。

根据@SternK 的建议,我已更改:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id",updatable = false)
private CashAccount cashAccount;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cashaccountid")
private CashAccount cashAccount;

但现在我收到错误

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "INSERT INTO creditaccount VALUES (1,1)" via JDBC Statement
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applysqlString(SchemaCreatorImpl.java:439) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applyImportSources(SchemaCreatorImpl.java:492) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.performCreation(SchemaCreatorImpl.java:180) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:135) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:121) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:156) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:316) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean.createNativeEntityManagerFactory(LocalContainerEntityManagerfactorybean.java:365) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerfactorybean.buildNativeEntityManagerFactory(AbstractEntityManagerfactorybean.java:391) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) ~[na:na]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:835) ~[na:na]
Caused by: java.sql.sqlDataException: data exception: bad value for CAST
    at org.hsqldb.jdbc.JDBCUtil.sqlException(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.jdbc.JDBCUtil.sqlException(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.jdbc.JDBCStatement.fetchResult(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.jdbc.JDBCStatement.execute(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95) ~[HikariCP-3.4.5.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-3.4.5.jar:na]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
    ... 18 common frames omitted
Caused by: org.hsqldb.HsqlException: data exception: bad value for CAST
    at org.hsqldb.error.Error.error(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.error.Error.error(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.Scanner.convertToNumber(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.types.NumberType.convertToType(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.StatementDML.getInsertData(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.StatementInsert.getResult(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.StatementDMQL.execute(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.Session.executeCompiledStatement(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.Session.executeDirectStatement(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    at org.hsqldb.Session.execute(UnkNown Source) ~[hsqldb-2.5.1.jar:2.5.1]
    ... 23 common frames omitted

解决方法

  1. 我猜是这样的:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id",insertable = false,updatable = false)
private CashAccount cashAccount;

应该像这样更正:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cashaccountid")
private CashAccount cashAccount;
  1. 正如本article中所建议的:

确保您将值映射到查询中的正确列。 最好的方法是在查询中定义列名和值。

因此,我建议您按以下方式重写 insert 语句:

INSERT INTO cashaccount(id,number,username,availablebalance,description)
VALUES (1,'10669803404133150948','ray',3424.32,'Checking Account');
...
INSERT INTO creditaccount(id,description,cashaccountid)
VALUES
(1,'4024 0071 5848 6471','Visa Gold',1);
...