Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.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 Hibernate删除删除所有行,然后插入行_Java_Hibernate_Jpa - Fatal编程技术网

Java Hibernate删除删除所有行,然后插入行

Java Hibernate删除删除所有行,然后插入行,java,hibernate,jpa,Java,Hibernate,Jpa,下面的例子被简化了 我有以下数据库结构: X -xid VARCHAR Y -yid VARCHAR -xid VARCHAR -zid VARCHAR Z -zid VARCHAR 我有以下实体结构 @Entity @Table(name = "X") public class EntityX { @Id @Column(name = "xid") private String xid; @OneToMany(... mappedBy = "x"

下面的例子被简化了

我有以下数据库结构:

X
 -xid VARCHAR

Y
 -yid VARCHAR
 -xid VARCHAR
 -zid VARCHAR
Z
 -zid VARCHAR
我有以下实体结构

@Entity
@Table(name = "X")
public class EntityX {
    @Id
    @Column(name = "xid")
    private String xid;

    @OneToMany(... mappedBy = "x", cascadeType.ALL, orphanRemoval=true)
    private List<EntityY> yList = new ArrayList();
    ...
}

@Entity
@Table(name = "Y")
public class EntityY {  
    @Id
    @Column(name = "yid")
    private String yid;

    @ManyToOne(cascadeType.ALL)
    private x;

    @ManyToOne(cascadeType.ALL)
    private z;
    ...
}

@Entity
@Table(name = "Z")
public class EntityZ {
    @Id
    @Column(name = "zid")
    private String zid;
}
我的更新方法是:

X x = new X();
x.setXid(1);

Z z = new Z();
z.setZid(1);

Z z2 = new Z();
z2.setZid(2);

Y y = new Y();
y.setYid(1);
y.setX(x);
y.setZ(z);

Y y2 = new Y();
y2.setYid(2);
y2.setX(x);
y2.setZ(z2);

List<Y> yList = new ArrayList<Y>();
yList.add(y);
yList.add(y2);
x.setYList(yList);

entityManager.persist(x);
X x = new X();
x.setXid(1);

Z z = new Z();
z.setZid(1);

Z z3 = new Z();
z3.setZid(3);

Y y = new Y();
y.setYid(1);
y.setX(x);
y.setZ(z);

Y y3 = new Y();
y3.setYid(3);
y3.setX(x);
y3.setZ(z3);

List<Y> yList = new ArrayList<Y>();
yList.add(y);
yList.add(y3);
x.setYList(yList);

entityManager.merge(x);

为什么Y(
YID=1
)和Z(
ZID=1
)在插入后被删除?例如,如果有100000次Y和Z未更改,则这是一个性能问题

尝试更新时,不要再次尝试手动创建实体并执行合并。当您在上面的相关实体上设置了级联选项时,您最终会遇到问题

在合并期间,持久性上下文将检索x(xid=1)实体以及OneToMany列表。新创建的X实体有一个新的list实例。现在,持久性提供程序考虑了
孤立删除
标志,并确定以前的状态无效。任何删除xid=1的Y的所有内容(因为它们不在新列表中)

然后在新列表中插入新添加的元素

我建议先获取xid=1的X,然后在持久性上下文管理的实体上执行更新:

X x = session.get(X.class, 1);
...

List<Y> yList = x.getYList();
yList.add(y);
yList.add(y3);

entityManager.merge(x);
X=session.get(X.class,1);
...
List yList=x.getYList();
添加(y);
yList.add(y3);
entityManager.merge(x);

在一个事务方法中实现所有功能。

Hibernate是如何工作的?save方法将数据保存到数据库中。Hibernate如何知道什么是“新创建的X”。它正在使用缓存吗?我尝试使用flush,但没有用。它使用代理对象,还检查某个对象是否在持久性上下文中(类似于单会话缓存)。同花顺在这里帮不了什么忙。同样,最好的办法是在更新实体之前检索该实体。。不是一直从头开始创建它,我认为当实体及其子实体被更新时,这会使逻辑复杂化。删除子项时,您必须手动检测哪些子项被删除。我希望Hibernate能帮我完成这项工作。我举了一个例子,其中没有enties EntityZ,而且删除效果很好。在更新之前没有检索到entity EntityX。我不是说这永远不会起作用。。这只是不可取的方式,特别是在设置了级联操作的情况下。
insert into Z (ZID) values (3);
insert into Y (YID, XID, ZID) values (3, 1, 3);

delete from Y where XID=1; Why?
delete from Z where XID=1; Why?
delete from Y where XID=2;
delete from Z where XID=2;

insert into Z (ZID) values (1); Why?
insert into Y (YID, XID, ZID) values (1, 1, 1); Why?
X x = session.get(X.class, 1);
...

List<Y> yList = x.getYList();
yList.add(y);
yList.add(y3);

entityManager.merge(x);