Spring Roo,JPA。级联问题。删除表违反了外键约束

时间:2012-02-07 12:13:07

标签: hibernate jpa spring-roo jpql

我有这样的配置:

@RooJavaBean
@RooToString
@RooEntity(table = "reo")
public class Reo {

    @OneToMany(cascade=CascadeType.ALL, mappedBy = "reo")
    private Set<ReoDescription> descriptions = new HashSet<ReoDescription>();
    ....
}

@RooJavaBean
@RooToString
@RooEntity(table = "description")
public class ReoDescription {
    @ManyToOne
    private Reo reo;
    ....
}

当我尝试使用JPQL删除reo对象时:

Query query = this.entityManager.createQuery("delete from Reo r where r.company = :company");
query.setParameter("company", comp);
query.executeUpdate();

我收到错误。 Stacktrace是帖子的底部。

但是当我尝试逐个删除它们时:

List<Reo> findReosOfCompany = Reo.findReosOfCompany(company);
for (Reo reo : findReosOfCompany) {
    reo.remove();
}

@Transactional
public void Reo.remove() {
   if (this.entityManager == null) this.entityManager = entityManager();
   if (this.entityManager.contains(this)) {
       this.entityManager.remove(this);
   } else {
       Reo attached = Reo.findReo(this.id);
       this.entityManager.remove(attached);
   }
}

一切都好。但我对此并不满意,因为它很难看。 可能是什么问题?

org.postgresql.util.PSQLException: ERROR: update or delete on table "reo" violates foreign key constraint "fk993583fceeb2fb9e" on table "description"
Detail: Key (id)=(47) is still referenced from table "description".
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2077)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1810)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:498)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:386)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:332)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:101)
at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:421)
at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:283)
at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1288)
at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:117)
at org.hibernate.ejb.QueryImpl.internalExecuteUpdate(QueryImpl.java:188)
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:99)
at ee.city24.exp.bean.Reo.deleteAllReosForCompany(Reo.java:480)
at ee.city24.exp.bean.Reo.deleteAllReosOfCompany_aroundBody4(Reo.java:466)
at ee.city24.exp.bean.Reo.deleteAllReosOfCompany(Reo.java:1)
at ee.city24.exp.scheduler.ScheduledCompanyUpdateJob.run(ScheduledCompanyUpdateJob.java:34)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)

org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: could not execute update query; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute update query
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:311)
at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:15)
at ee.city24.exp.bean.Reo.deleteAllReosForCompany(Reo.java:480)
at ee.city24.exp.bean.Reo.deleteAllReosOfCompany_aroundBody4(Reo.java:466)
at ee.city24.exp.bean.Reo.deleteAllReosOfCompany(Reo.java:1)
at ee.city24.exp.scheduler.ScheduledCompanyUpdateJob.run(ScheduledCompanyUpdateJob.java:34)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute update query
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148)
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1225)
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:108)
... 14 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute update query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:110)
at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:421)
at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:283)
at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1288)
at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:117)
at org.hibernate.ejb.QueryImpl.internalExecuteUpdate(QueryImpl.java:188)
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:99)
... 14 more
Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "reo" violates foreign key constraint "fk993583fceeb2fb9e" on table "description"
Detail: Key (id)=(47) is still referenced from table "description".
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2077)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1810)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:498)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:386)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:332)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:101)
... 20 more

1 个答案:

答案 0 :(得分:1)

http://docs.oracle.com/cd/E16764_01/apirefs.1111/e13946/ejb3_langref.html#ejb3_langref_bulk_ops

&#34;删除操作仅适用于指定类及其子类的实体。它不会级联到相关实体。 &#34;

所以通过EntityManager删除操作#remove似乎是合理的。