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
, CONSTRAINTB_FK1
FOREIGN KEY (A_A_ID_OID
) REFERENCESa
(A_ID
))