【问题标题】:Wrong auto increment in embedded Derby/ Java DB嵌入式 Derby/Java DB 中的错误自动增量
【发布时间】:2015-11-14 03:54:01
【问题描述】:

我正在开发一个以嵌入式模式使用 Apache Derby 数据库的会计程序。我有一个包含两列的表分支:

CREATE TABLE Branch(
     idBranch INT NOT NULL PRIMARY KEY 
     GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), 
     place VARCHAR(255) NOT NULL
);

当我在 Branch 表中插入新记录时,自动递增 1 无法正常工作。 我得到以下结果:

+----------+
| idBranch |
+----------+
| 1        |
| 101      |
| 201      |
| 301      |
+----------+

但结果应该如下:

+----------+
| idBranch |
+----------+
| 1        |
| 2        |
| 3        |
| 4        |
+----------+

这是我连接到数据库的方式:

private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";

public static Connection createConnection() {
    Connection connection = null;
    try {
        Class.forName(DRIVER);
        connection = DriverManager.getConnection("jdbc:derby:" + DATABASE);
    } catch (ClassNotFoundException ex) {
        logger.log(Level.SEVERE, "JDBC Driver not loaded!", ex);
        System.exit(1);
    } catch (SQLException ex) {
        // create the database
        DerbyDB derbyDB = new DerbyDB();
        connection = derbyDB.create();
    }
    return connection;
}

下面是在Branch表中插入新记录的方法:

private static final String CREATE_QUERY = "INSERT INTO Branch(place) VALUES(?)";

public int createBranch(Branch branch) {
    Connection connection = DerbyDAOFactory.createConnection();
    try {
        PreparedStatement statement = connection.prepareStatement(CREATE_QUERY, Statement.RETURN_GENERATED_KEYS);
        statement.setString(1, branch.getPlace());
        statement.execute();
        ResultSet result = statement.getGeneratedKeys();
        if(result.next()) {
            return result.getInt(1);
        }
    } catch (SQLException ex) {
        logger.log(Level.SEVERE, null, ex);
    }
    return -1;
}

为什么我会得到这个结果?

【问题讨论】:

  • 请显示您的查询CREATE_QUERY
  • @Jens CREATE_QUERY = "INSERT INTO Branch(place) VALUES(?)";

标签: java jdbc derby


【解决方案1】:

您观察到的序列是此错误的结果:https://issues.apache.org/jira/browse/DERBY-5151

以下文档描述了它发生的原因:https://db.apache.org/derby/docs/10.9/ref/rrefproperpreallocator.html

总结... 生成的值是预先分配的(默认情况下一次 100 个值)。当数据库被错误地关闭时,那些预先分配的值被泄露——它们被简单地丢弃,当数据库再次启动时,分配器开始计算它停止的位置(在序列中引入一个间隙)。

换句话说,这是预期的行为 - 为避免这种情况,请确保您以有序的方式关闭数据库:

DriverManager.getConnection("jdbc:derby:;shutdown=true")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多