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 返回的 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, CONSTRAINT B_FK1FOREIGN KEY ( A_A_ID_OID) REFERENCES a( A_ID))

4

0 回答 0