0

MySQL の DataNucleus 3.1.3 で単純な 2 つのクラスを永続化する際に問題があり、DataNucleus が無効な外部キーを作成しているように見え、データベースからの「外部キー制約の失敗」という例外が発生します。

ここに私のクラス:

// datastore since i dont care about identity here
@PersistenceCapable(identityType = IdentityType.DATASTORE)
class A {
    @Persistent
    int x;
    @Persistent
    int y;
}

// identity type:application here to enable id lookups
@PersistenceCapable
class B {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.NATIVE)
    long id;

    @Persistent
    double longitude;
    @Persistent
    double latitude;
    // simple 1:1 unidirectional
    @Persistent
    A a;
}

schemaTool は、良さそうなテーブル (InnoDB) を作成しましたが、挿入に失敗しました。ログは次のとおりです。

12:54:11,369 DEBUG [DataNucleus.Datastore.Native] - INSERT INTO `A` (`X`,`Y`) VALUES (<1>,<1>)
12:54:11,387 DEBUG [DataNucleus.Datastore.Persist] - Execution Time = 18 ms (number of rows = 1)
12:54:11,398 DEBUG [DataNucleus.Datastore.Persist] - Object "foo.A@624af1e" was inserted in the datastore and was given strategy value of "3"
12:54:11,403 DEBUG [DataNucleus.Datastore] - Closing PreparedStatement "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@6f5ba238"
12:54:11,404 DEBUG [DataNucleus.Datastore.Native] - INSERT INTO `B` (`LONGITUDE`,`LATITUDE`,`A_A_ID_OID`) VALUES (<0.5099776394799052>,<0.6191090630996077>,<51>)
12:54:11,419 WARN  [DataNucleus.Datastore.Persist]  ... Cannot add or update a child row: a foreign key constraint fails (`xperimental`.`B`, CONSTRAINT `B_FK1` FOREIGN KEY (`A_A_ID_OID`) REFERENCES `A` (`A_ID`))

行 (3) と (5) のログを見ると、テーブル A への挿入が "3" の PK を返したことが非常に疑わしいですが、DataNucleus は代わりにテーブル B にデータを挿入するときに A の FK として "51" の値を使用します。違反を引き起こします。

問題はどこにありますか?ありがとう

更新: リソース

クラスA

package jdotest.a;

import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;

@PersistenceCapable(identityType = IdentityType.DATASTORE)
public class A {
  @Persistent
  private int x;
  @Persistent
  private int y;

  public int getX() {
    return x;
  }

  public int getY() {
    return y;
  }
}

クラスB

package jdotest.b;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import jdotest.a.A;

@PersistenceCapable
public class B {
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.NATIVE)
  long   id;

  @Persistent
  double longitude;
  @Persistent
  double latitude;
  // simple 1:1 unidirectional
  @Persistent
  A      a;

  public long getId() {
    return id;
  }

  public double getLongitude() {
    return longitude;
  }

  public double getLatitude() {
    return latitude;
  }

  public void setA(A a) {
    this.a = a;
  }

  public A getA() {
    return a;
  }
}

ダオ

package dao;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Transaction;

import jdotest.b.B;

public class BDao {
  public void write(B b) {
    PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("cloud-sql");
    PersistenceManager pm = pmf.getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();
      pm.makePersistent(b);
      tx.commit();
    } finally {
      if (tx.isActive())
        tx.rollback();
      pm.close();
    }
  }
}

実行

  package exec;

  import jdotest.a.A;
  import jdotest.b.B;
  import dao.BDao;

  public class Ex{
    public void persist(){
      A a = new A();
      B b = new B();
      b.setA(a);
      new BDao().write(b); //<-- exception
    }
  }    
  • 例外 *

    java.sql.SQLException: 子行を追加または更新できません: 外部キー制約が失敗しました ( xperimental. b, CONSTRAINT B_FK1FOREIGN KEY ( A_A_ID_OID) REFERENCES a( A_ID))

4

0 に答える 0