Play framework 2.0尝试级联删除时出错“参数”#1“未设置; SQL语句:删除”

时间:2012-08-30 07:13:06

标签: java jpa playframework-2.0 h2 ebean

我的示例中的完整错误行是“[PersistenceException:org.h2.jdbc.JdbcSQLException:参数”#1“未设置; SQL语句:从class4中删除(class3_id)in(?)[90012-158 ]]“

这是在我的单元测试中发生的,因此决定创建一个测试项目来尝试重现它并且确实如此。

基本上我有1-4个类,每个类都与onetomany相关,我试图创建它们然后按1,2,3,4 4,3,2,1的顺序删除它们但是我得到了这个错误。

除了数字之外,这些类都是相同的(并且最后一个类没有列表

@Entity
public class Class1 extends Model{

/**
 * 
 */
private static final long serialVersionUID = 4322329984247299024L;

@Id
@GeneratedValue
public Long id;



@OneToMany(mappedBy="class1",cascade={CascadeType.PERSIST, CascadeType.ALL})
private List<Class2> class2s = new ArrayList<Class2>();

public Class2 add()
{
    Class2 class2 = new Class2(this);
    Class2.create(class2);
    return class2;
}


@play.db.ebean.Transactional 
public static void create(Class1 class1) {
    class1.save();
    }



  @play.db.ebean.Transactional 
 public static void delete(Class1 class1) {
      class1.delete();
    }
}

导致错误的应用程序代码如下所示

      Class1 class1 = new Class1();
  Class1.create(class1);
  Class2 class2 = class1.add();
  class1.add();

  Class2.delete(class2);
  Class1.delete(class1);

我还附上了一个显示它正在发生的示例应用程序,如果有人可以指出我做错了什么,或者如果有人知道我可以解决它的问题,那么我会非常感激。< / p>

http://stowelly.co.uk/play-2.0.3-persistence-test.zip

谢谢

2 个答案:

答案 0 :(得分:2)

似乎这是Ebean中的一个错误

http://www.avaje.org/bugdetail-420.html

无论如何,这是一个临时的解决方法,而这是解决了每个类删除函数中的以下代码

 @play.db.ebean.Transactional 
     public static void delete(Class2 class2)
  {  
     List<Class3> list = class2.getClass3s();
     for(int i = 0; i < list.size(); ++i)
     {
       Class3.delete(list.get(i));
     }  
     list.clear();
     class2.getClass1().getClass2s().remove(class2);
     class2.delete();
    }

答案 1 :(得分:1)

请勿在您的实体中使用@Transactional之类的内容。而是在业务逻辑/持久性上使用它。

@Entity
public class A
{
    Long id;
    List<B> bs;

    //...
}

public class DAO
{
    @Transactional
    public void addBtoA(A a, B b)
    {
         b = em.persist(b);
         a = em.find(a);
         a.addB(b);
         em.persist(a);
    }
}

简单的解释是事务存在,所以如果出现问题就可以回滚。这是为了防止半持久化内容,在提交B示例中,A不存在,B是数据库中未引用的条目。