Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 玩删除时的框架引用完整性约束_Java_Hibernate_Model_Playframework_Associations - Fatal编程技术网

Java 玩删除时的框架引用完整性约束

Java 玩删除时的框架引用完整性约束,java,hibernate,model,playframework,associations,Java,Hibernate,Model,Playframework,Associations,我创建了一些模型对象来表示具有多个客户的公司,以及由公司和客户组合以及多个发票行组成的发票对象。我已创建了以下模型对象: @Entity public class Company extends Model { @OneToMany(mappedBy="company") public Set<Client> clients; } @Entity public class Client extends Model { @ManyToOne publi

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

@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;
}
@实体
上市公司扩展模型{
@OneToMany(mappedBy=“公司”)
公共设置客户端;
}
@实体
公共类客户端扩展模型{
@许多酮
上市公司;
}
@实体
公共类发票扩展模型{
@许多酮
上市公司;
@许多酮
公共客户;
@OneToMany(mappedBy=“invoice”,cascade=CascadeType.ALL)
公共设置发票行;
}
@实体
公共类InvoiceLine扩展模型{
@许多酮
公共发票;
}
测试:

@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());
@测试
公共void testModels(){
Client=createClient();
公司=createCompany();
company.clients=new HashSet();
公司。客户。添加(客户);
company.save();
发票=创建发票(客户、公司);
发票行发票行1=创建发票行(发票);
发票行发票行2=创建发票行(发票);
Set invoiceLines=new HashSet();
发票行。添加(发票行1);
发票行。添加(发票行2);
invoice.invoiceLines=发票行;
invoice.save();
Company retrievedCompany=Company.find(“byName”,Company.name).first();
assertNotNull(检索公司);
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外键(发票ID)引用>PUBLIC.INVOICE(ID)”; SQL语句:从发票中删除[23003-149]


我做错了什么?

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


请先尝试删除发票行,然后再删除发票。

您是否已尝试使用
发票。删除()
?问题是
deleteAll()
没有级联删除操作

deleteAll()
在内部使用
javax.persistence.Query
,而
delete()
使用
EntityManager
remove()
方法。JPA中的级联由JPA处理,而不是由数据库处理,并且JPA不会像由
deleteAll()
执行的那样级联批量删除

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

也许下面的单元测试可以解决问题。
Parent1
就像您的
发票一样。而
Child1
就像你的
InvoiceLine

import java.util.*;
import javax.persistence.*;
import org.junit.*;
import play.test.*;
import models.*;

public class Parent1Test extends UnitTest {

    public Parent1 p;
    public Child1 c1;
    public Child1 c2;
    public Child1 c3;

    @Before
    public void setUp() {
        Fixtures.deleteAllModels();

        p = new Parent1();
        c1 = new Child1();
        c2 = new Child1();
        c3 = new Child1();
    }

    public void byAddingParentToChilds() {
        c1.parent = p;
        c2.parent = p;
        c3.parent = p;

        c1.save();
        c2.save();
        c3.save();
        p.refresh();
    }

    @Test
    public void testByAddingParentToChilds() {
        byAddingParentToChilds();
        assertEquals(p.id, c1.parent.id);
        assertEquals(3, Child1.count());
    }

    public void byAddingChildsToParent() {
        p.childs = new ArrayList<Child1>();
        p.childs.add(c1);
        p.childs.add(c2);
        p.childs.add(c3);
        p.save();
    }

    @Test
    public void testByAddingChildsToParent() {
        // By adding childs
        byAddingChildsToParent();

        c1.refresh();
        assertEquals(3, Child1.count());
        // This will be null, because you added the childs to the 
        // parent while the childs are the owning side of the 
        // relation.
        assertNull(c1.parent);
    }

    @Test
    public void testDeletingAfterAddingParentToChilds() {
        byAddingParentToChilds();
        p.delete();
        assertEquals(0, Parent1.count());
        assertEquals(0, Child1.count());
    }

    @Test
    public void testDeletingAfterAddingChildsToParent() {
        byAddingChildsToParent();
        p.delete();
        assertEquals(0, Parent1.count());
        assertEquals(0, Child1.count());
    }

    @Test(expected=PersistenceException.class)
    public void testDeleteAllAfterAddingParentToChilds() {
        byAddingParentToChilds();
        // The cascading doesn't work for deleteAll() so this line
        // will throw an exception because the child elements still
        // reference the parent.
        assertEquals(1, Parent1.deleteAll());
    }

    @Test
    public void testDeleteAllAfterAddingChildsToParent() {
        byAddingChildsToParent();
        assertEquals(1, Parent1.deleteAll());
        assertEquals(0, Parent1.count());
        // Again the cascading doesn't work for deleteAll()
        assertEquals(3, Child1.count());
    }

}
import java.util.*;
导入javax.persistence.*;
导入org.junit.*;
导入play.test.*;
进口型号。*;
公共类Parent1Test扩展了UnitTest{
公共家长1 p;
公共儿童1 c1;
公共儿童1 c2;
公共儿童1 c3;
@以前
公共作废设置(){
Fixtures.deleteAllModels();
p=新的父母1();
c1=新子女1();
c2=新子女1();
c3=新子女1();
}
通过将ParentToChilds()添加为公共无效{
c1.父母=p;
c2.父母=p;
c3.父母=p;
c1.save();
c2.save();
c3.save();
p、 刷新();
}
@试验
通过将ParentToChilds()添加到公共无效测试{
通过将ParentToChilds()添加到;
资产质量(p.id,c1.parent.id);
assertEquals(3,Child1.count());
}
通过添加childstoparent()公共无效{
p、 childs=newarraylist();
p、 添加(c1);
p、 添加(c2);
p、 childs.add(c3);
p、 save();
}
@试验
通过添加childstoparent()进行的公共无效测试{
//通过添加child
通过添加childstoparent();
c1.刷新();
assertEquals(3,Child1.count());
//这将为null,因为您已将child添加到
//父母,而孩子是家庭的拥有方
//关系。
assertNull(c1.父级);
}
@试验
添加ParentToChilds()后的公共无效测试删除{
通过将ParentToChilds()添加到;
p、 删除();
assertEquals(0,Parent1.count());
assertEquals(0,Child1.count());
}
@试验
添加ChildStoparent()后的公共无效测试删除{
通过添加childstoparent();
p、 删除();
assertEquals(0,Parent1.count());
assertEquals(0,Child1.count());
}
@测试(预期=PersistenceException.class)
public void testDeleteAllAfterAddingParentToChilds(){
通过将ParentToChilds()添加到;
//级联不适用于deleteAll(),因此此行
//将引发异常,因为子元素仍然
//引用父对象。
assertEquals(1,Parent1.deleteAll());
}
@试验
public void testDeleteAllAfterAddingChildsToParent(){
通过添加childstoparent();
assertEquals(1,Parent1.deleteAll());
assertEquals(0,Parent1.count());
//同样,级联对deleteAll()不起作用
assertEquals(3,Child1.count());
}
}

请添加测试代码以查看步骤感谢您的回复。问题似乎与JPA有关,而不是与游戏有关!框架我想要的行为是,当与发票相关的发票被删除时,发票行被自动删除。我在想,通过将CascadeType.ALL和orphanRemoving设置为true,我将得到这种行为,但实际上