我在 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 返回的 PK 为“3”,但 DataNucleus 在将数据插入表 B 时使用 A 上的值“51”作为 FK导致违规。
问题出在哪里?谢谢
更新:资源
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
))