玩!删除框架参照完整性约束

时间:2012-03-06 14:26:58

标签: java hibernate model playframework associations

我创建了一些Model对象来表示具有多个客户端的公司,以及一个由公司和客户组合以及多个发票行组成的发票对象。我创建了以下Model对象:

@Entity
public class Company extends Model {
    @OneToMany(mappedBy="company")
    public Set<Client> clients;
}

@Entity
public class Client extends Model {
    @ManyToOne
    public Company company;
}

@Entity
public class Invoice extends Model {
    @ManyToOne
    public Company company;
    @ManyToOne
    public Client client;
    @OneToMany(mappedBy="invoice", cascade=CascadeType.ALL)
    public Set<InvoiceLine> invoiceLines;
}

@Entity
public class InvoiceLine extends Model {
    @ManyToOne
    public Invoice invoice;
}

测试:

@Test
public void testModels() {
    Client client = createClient();
    Company company = createCompany();
    company.clients = new HashSet<Client>();
    company.clients.add(client);
    company.save();

    Invoice invoice = createInvoice(client, company);
    InvoiceLine invoiceLine1 = createInvoiceLine(invoice);
    InvoiceLine invoiceLine2 = createInvoiceLine(invoice);
    Set<InvoiceLine> invoiceLines = new HashSet<InvoiceLine>();
    invoiceLines.add(invoiceLine1);
    invoiceLines.add(invoiceLine2);
    invoice.invoiceLines = invoiceLines;
    invoice.save();

    Company retrievedCompany = Company.find("byName", company.name).first();
    assertNotNull(retrievedCompany);
    assertEquals(1, retrievedCompany.clients.size());
    assertEquals(2, InvoiceLine.count());

    assertEquals(1, Invoice.deleteAll());
    assertNull(Invoice.all());
    assertNull(InvoiceLine.all());

}

运行使用两个发票行创建发票的测试并尝试删除此发票时,我收到以下错误:

  

org.h2.jdbc.JdbcSQLException:参照完整性约束违规:   “FK3004B0A1F4110EF6:PUBLIC.INVOICELINE FOREIGN KEY(INVOICE_ID)REFERENCES&gt; PUBLIC.INVOICE(ID)”;   SQL语句:从Invoice [23003-149]

中删除

我做错了什么?

2 个答案:

答案 0 :(得分:3)

您是否尝试使用invoice.delete()?问题是deleteAll()没有级联删除操作。

deleteAll()在内部使用javax.persistence.Query,而delete()使用EntityManager的{​​{1}}方法。 JPA中的级联由JPA处理,而不是由数据库处理,JPA不会像remove()执行的那样级联批量删除。
Check this link for more info on bulk delete/update

另外:如果您已将deleteAll()设置为Invoice中的父级,则将InvoiceLine实体添加到Invoice是多余的。在执行断言之前,只需执行createInvoiceLine()

也许以下单元测试可以解决问题。 invoice.refresh()就像您的Parent1一样。虽然Invoice与您的Child1类似。

InvoiceLine

答案 1 :(得分:0)

您正在尝试删除所有发票,但仍有一些InvoiceLines链接到它。

首先尝试删除发票行和发票。