1

Squeryl を使用して、あるデータベースからテーブルの内容を取得し、それを別のデータベースの同等のテーブルに追加しようとしています。プロセスで主キーを再割り当てする必要がありますが、エラーNULL not allowed for column "SIMID" が表示されます。どうしてこれなの?

object Concatenator {
  def main(args: Array[String]) {
    Class.forName("org.h2.Driver");

    val seshA = Session.create(
      java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsA", "sa", "password"),
      new H2Adapter
    )

    val seshB = Session.create(
      java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsB", "sa", "password"),
      new H2Adapter
    )

    using(seshA){
      import Library._
      from(sims){s => select(s)}.foreach{item =>
        using(seshB){
          sims.insert(item);
        }
      }
    }

  }

  case class Simulation(
    @Column("SIMID")
    var id: Long, 
    val date: Date
  ) extends KeyedEntity[Long]

  object Library extends Schema {
    val sims = table[Simulation]

    on(sims)(s => declare(
      s.id is(unique, indexed, autoIncremented)
    ))
  }
}

更新: DB と関係があるのではないかと思います。それらは、JPA/EclipseLink を使用して Java プロジェクトで作成され、エンティティのテーブルを生成するだけでなく、おそらく主キー生成用に SEQUENCE というテーブルも作成しました。

Squeryl でまったく新しいテーブルを作成し、その中に両方のデータベースの内容を手動で配置して、同じ効果を達成できることを発見しました。興味深いことに、この新しいテーブルには自動生成された SEQUENCE テーブルがありませんでした。だから、JPA/EclipseLinkが主キーをどのように生成していたかに帰着すると思いますか?

更新 2: 要求に応じて、URL に trace_level_file=3 を追加しました。ファイルはここにあります: resultsA.trace.dbおよびresultsB.trace.db。Bの方が面白いと思います。また、不要なテーブルを削除した簡易バージョンのデータベースをここに配置しました (同じデータベースが resultsA と resultsB に使用されます)。

4

2 に答える 2

1

これをもっと詳しく見てみましょう。あなたは正しい軌道に乗っていたことがわかりました。EclipseLink はシーケンスを使用して PK 値を生成していると思いますが、Squeryl は列を次のように定義します。

simid bigint not null 主キーauto_increment

auto_increment フラグがないと、列に値が配置されず、言及した制約違反が発生します。すでに問題を回避しているようですが、これが将来あなたや他の誰かに役立つことを願っています.

于 2011-11-25T18:56:02.697 に答える
0

Not really a solution, but my workaround is to create a new database

val seshNew = Session.create(java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsNew", "sa","password"),new H2Adapter)

and then just write all the data from the other databases into it

using(seshNew){
    sims.insert(new Simulation(0,item.date))
}

The primary keys 0 gets overwritten as appropriate.

于 2011-11-23T11:55:55.283 に答える