2012-02-19 11 views
1

HSQLDBを組み込みデータベースとして使用したいが、自動インクリメントに問題があります。HSQLDB(2.2.8)+ DDLUtilsによる自動インクリメント

私が理解する限り、[CALL] IDENTITY()を使用して、最後の主キー値を取得できます。しかし、iBatisとHSQLDBのDatabaseManagerSwingの両方を使った実験では、常に0の値が返されます。

HSQLDBで自動インクリメントを使用するにはどうすればよいですか?

編集:

私は、テーブルを自動生成するDDLUtilsを使用していることに言及しませんでした。次スーツHSQLDBしません:

<?xml version="1.0"?> 
<!DOCTYPE database SYSTEM "http://db.apache.org/torque/dtd/database.dtd"> 

<database name="testdb"> 

    <table name="users"> 
     <!-- using autoincrement attribute below causes 
     "primary key already exists" exception --> 
     <column name="id" type="INTEGER" primaryKey="true" /> 
     <column name="username" type="VARCHAR" size="30" /> 
     <column name="password" type="VARCHAR" size="100" /> 
    </table> 

</database> 

はまた、ここではドメインクラスで使用iBatisのSQLマップです:

<insert id="insertUser" parameterClass="user"> 
    <selectKey keyProperty="id" resultClass="int"> 
     CALL IDENTITY() 
    </selectKey> 
INSERT INTO USERS 
(USERNAME, PASSWORD) 
VALUES 
(#username#, #password#)  
</insert> 
+0

どのようなバージョンのHSQLDBを使用しますか? –

+0

@EmmanuelBourgおそらく最新の2.2.8です。 –

+0

これは問題の原因かもしれません:http://stackoverflow.com/questions/4857730/how-to-fix-hsql-datasource-txm-where-identity-always-return-0 –

答えて

4

はここ

0 
1 
2 

を出力例を示します私のマシン上:

import java.io.File; 

import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.Statement; 
import java.sql.ResultSet; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.sql.Date; 

public class Test { 

    public static void main(String[] args) throws Exception { 

    File dbDir = new File("/tmp/identity_test"); 
    String connectionTemplate = "jdbc:hsqldb:file:%s/test"; 
    String connStr = String.format(connectionTemplate, dbDir); 
    Connection connection = DriverManager.getConnection(connStr, "", ""); 
    Statement s = connection.createStatement(); 
    s.execute("CREATE TABLE test (id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, s VARCHAR(10))"); 
    PreparedStatement psInsert = connection.prepareStatement("INSERT INTO test (s) VALUES (?)"); 
    for (int i = 0; i < 3; i++) { 
     psInsert.setString(1, "hello"); 
     psInsert.executeUpdate(); 
     PreparedStatement psIdentity = connection.prepareStatement("CALL IDENTITY()"); 
     ResultSet result = psIdentity.executeQuery(); 
     result.next(); 
     int identity = result.getInt(1); 
     result.close(); 
     System.out.println(identity); 
    } 
    connection.close(); 
    } 
} 
+0

テーブルの作成に使用したSQLは、「GENERATED ALWAYS AS IDENTITY」というソリューションを提供しました。 XMLを使って自動的にテーブルを生成するためにApache DDLUnitを使用しているとは言いませんでした。私はこの目的のために別の枠組みを模索するつもりです。 –

1

ORMを使用すると、ID列作業が実行されます。 sormulaは、アノテーションで簡単にできます。例については、プロジェクト内のorg.sormula.tests.identityパッケージを参照してください。 org.sormula.identity.tests.InsertTestから

public class IdentityTest 
{ 
    @Column(identity=true) 
    int id; 
    ... 

行クラス定義された

IdentityTest row = new IdentityTest(-1, "Insert one"); 
assert getTable().insert(row) == 1 : "insert one failed"; 
assert row.getId() > 0 : "indentity column was not generated"; 

HSQLDBは​​テストに含まれています。