OpenJPA:级联删除抛出PersistenceException

时间:2015-03-26 00:41:32

标签: java jpa-2.0 openjpa

我已经离开Java世界一段时间了,我是JPA的新手。我有一个数据模型,其中WindTurbines可以有几个PerformanceCurves,而这些PerformanceCurves又包含几个PerfCurvePoints。我在关系上设置了cascade = CascadeType.ALL和orphanRemoval = true。

当我从WindTurbine中删除PerformanceCurve时,我得到一个PersistenceException,因为数据库中存在引用PerformanceCurve的PerfCurvePoint记录。

我预计PerfCurvePoint记录会与孤立​​的PerformanceCurve一起被自动删除,因为我在该关系上指定了CascadeType.ALL。

我知道我可以通过清除PerformanceCurve对象上的PerfCurvePoints集合并在从WindTurbine中删除PerformanceCurve之前调用EntityManager.flush()来解决这个问题,但我不喜欢在该层中引用EntityManager我们的申请。有没有更好的方法来解决这个问题?

@Entity
public class WindTurbine implements Serializable {

    @OneToMany(mappedBy="turbine", fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true)
    private ArrayList<PerformanceCurve> perfCurves = new ArrayList<>();

    ...

}


@Entity
public class PerformanceCurve implements Serializable {

    @ManyToOne(optional=false)
    @JoinColumn(name="TURBINE_ID", referncedColumnName="TURBINE_ID")
    private WindTurbine turbine;

    @OneToMany(mappedBy("perfCurve", fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true)
    private ArrayList<PerfCurvePoint> points = new ArrayList<>();

    ...

}

@Entity
public class PerfCurvePoint implements Serializable {

    @ManyToOne(optional=false)
    @JoinColumn(name="PERF_CURVE_ID", referncedColumnName="PERF_CURVE_ID")
    private PerformanceCurve perfCurve;

    ...

}

public class Foo {

    public void Bar(WindTurbine turbine) {
        // The following line causes a PersistenceException to be thrown
        //   on flush/commit if the performance curve contains any points.
        turbine.getPerformanceCurves().remove(1);
    }

    public void Workaround(EntityManager em, WindTurbine turbine) {
        // This works, but it requires a call to 
        //   EntityManager.flush() that I would like to avoid.
        PerformanceCurve curve = turbine.getPerformanceCurves().get(1);
        curve.getPoints().clear();
        em.flush();
        turbine.getPerformanceCurves().remove(curve);
    }
}

编辑:我实际上是在所有级联删除中获得PersistenceException,无论它们是否是孤立删除的结果。

1 个答案:

答案 0 :(得分:2)

事实证明,需要配置OpenJPA以便它知道数据库中现有的外键约束,否则它可能会在删除子节点之前尝试删除父节点。解决方案是将此行添加到persistence.xml:

<property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" />