删除parrent表JPA中的值时删除子表中的值

时间:2016-05-03 15:30:25

标签: jpa jpql java-ee-7

Parrent表:Currency - 有两个表示子表中外键的字段:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "inputCurrency")
List<Rate> ratesIC;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "outputCurrency")
List<Rate> ratesOC;

子表:Rate - has2字段引用parrent表中的主键:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "INPUT_CURRENCY")
private Currency inputCurrency;

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "OUTPUT_CURRENCY")
private Currency outputCurrency;

问题:如何删除货币以及包含该货币的所有汇率?我不想用 orphanRemoval = true来自Currency的ratesIC和ratesOC字段。

我尝试了什么: 我首先尝试删除包含该货币的所有费率:

@NamedQuery(
       name = "deleteRateByCurrencyName",
       query = "DELETE FROM Rate r "
       + "WHERE r.inputCurrency.currency = :cName "
       + "OR r.outputCurrency.currency = :cName")

然后删除父表中具有名称货币的货币:

@NamedQuery(
       name = "deleteCurrencyByCurrencyName",
       query = "DELETE FROM Currency c "
       + "WHERE c.currency =:cName")

我是通过调用此函数来完成的:

public void removeCurrencyByNameAndAllRatesContainingThatCurrency(String currency) throws CurrencyNotFoundException {
        try {
            em.createNamedQuery("deleteRateByCurrencyName")
                    .setParameter("cName", currency)
                    .executeUpdate();
            em.createNamedQuery("deleteCurrencyByCurrencyName")
                    .setParameter("cName", currency)
                    .executeUpdate();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new CurrencyNotFoundException("The currency " + currency + " doesn't exist!");
        }
    }

我得到了什么:

Internal Exception: java.sql.SQLIntegrityConstraintViolationException: DELETE on table 'CURRENCY' caused a violation of foreign key constraint 'RATEOUTPUTCURRENCY' for key (3).  The statement has been rolled back.
Error Code: 20000

1 个答案:

答案 0 :(得分:0)

我不知道您使用的是哪个JPA提供程序,因为您尝试的查询给了我一个不同的错误。在Wildfly 10下使用Hibernate 5.0.7.Final我得到以下工作:

em.createQuery("delete from Rate r where r in (select r from Rate r where r.inputCurrency.currency = :currency or r.outputCurrency.currency = :currency)")
    .setParameter("currency", "USD")
    .executeUpdate();
em.createQuery("delete from Currency where currency=:sCurrency")
    .setParameter("sCurrency", "USD")
    .executeUpdate();