I am using Play 2.0 framework, I have three classes, Patient
, Visit
and Puberty
. Patient
and Visit
have ManyToOne relationship, whereas Visit
and Puberty
have a one to one relationship (I know, it's bad practice in database design, but Visit
has a lot of variables, I want to separate them).
public class Patient{
@Id
public Long id;
@OneToMany (mappedBy="patient", cascade=CascadeType.ALL)
public List<Visit> visits;
}
public class Visit{
@Id
public Long id;
@ManyToOne (cascade=CascadeType.ALL)
public Patient patient;
@OneToOne(mappedBy="visit", cascade={CascadeType.ALL})
public Puberty puberty;
}
public class Puberty{
@Id
public Long id;
@OneToOne
public Visit visit;
}
When I called patient.delete()
where there is no puberty with visit, it works fine, but when there is puberty information under visit, the follow errors occurred:
play.api.Application$$anon$1: Execution exception[[PersistenceException: ERROR executing DML bindLog[] error[Referential integrity constraint violation: "FK_PUBERTY_DATA_VISIT_7: PUBLIC.PUBERTY_DATA FOREIGN KEY(VISIT_ID) REFERENCES PUBLIC.VISIT(ID) (100)"; SQL statement:\n delete from visit where id=? and patient_id=? [23503-168]]]] at play.api.Application$class.handleError(Application.scala:289) ~[play_2.10.jar:2.1.0] at play.api.DefaultApplication.handleError(Application.scala:383) [play_2.10.jar:2.1.0] at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:132) [play_2.10.jar:2.1.0] at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:128) [play_2.10.jar:2.1.0] at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.0] at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.0] javax.persistence.PersistenceException: ERROR executing DML bindLog[] error[Referential integrity constraint violation: "FK_PUBERTY_DATA_VISIT_7: PUBLIC.PUBERTY_DATA FOREIGN KEY(VISIT_ID) REFERENCES PUBLIC.VISIT(ID) (100)"; SQL statement:\n delete from visit where id=? and patient_id=? [23503-168]] at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:97) ~[avaje-ebeanorm-server.jar:na] at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.delete(DmlBeanPersister.java:48) ~[avaje-ebeanorm-server.jar:na] at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeDeleteBean(DefaultPersistExecute.java:109) ~[avaje-ebeanorm-server.jar:na] at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:489) ~[avaje-ebeanorm-server.jar:na] at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeOrQueue(PersistRequestBean.java:511) ~[avaje-ebeanorm-server.jar:na] at com.avaje.ebeaninternal.server.persist.DefaultPersister.delete(DefaultPersister.java:635) ~[avaje-ebeanorm-server.jar:na] Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FK_PUBERTY_DATA_VISIT_7: PUBLIC.PUBERTY_DATA FOREIGN KEY(VISIT_ID) REFERENCES PUBLIC.VISIT(ID) (100)"; SQL statement: delete from visit where id=? and patient_id=? [23503-168] at org.h2.message.DbException.getJdbcSQLException(DbException.java:329) ~[h2.jar:1.3.168] at org.h2.message.DbException.get(DbException.java:169) ~[h2.jar:1.3.168] at org.h2.message.DbException.get(DbException.java:146) ~[h2.jar:1.3.168] at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:414) ~[h2.jar:1.3.168] at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:431) ~[h2.jar:1.3.168] at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:307) ~[h2.jar:1.3.168]
I suspect it have something to do with the order Play delete stuffs, where it try to delete visit before puberty, Is there a way to overcome this using cascade? or should I override my delete method in visit to specify it myself?
Please help... thank you