JPA:在同一个实体上关联manyToMany [英] JPA: relation manyToMany on the same entity

查看:90
本文介绍了JPA:在同一个实体上关联manyToMany的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实体与自己有两个关系manyToMany,我不想使用Cascade.MERGE,因为我需要做一些数据检查来验证数据:

  @Entity(device)
public class Device {
...
@ManyToMany(mappedBy =parents,targetEntity = Device .class,fetch = FetchType.LAZY)
public Set< Device> getChildren(){
return this.children;

$ b @Override
@ManyToMany(targetEntity = Device.class,fetch = FetchType.LAZY)
@JoinTable(name =dem_hierarchy,joinColumns = {
@JoinColumn(name =DEM_DEVICE_UUID,referencedColumnName =UUID)})
@JoinColumn(name =CHILDREN_UUID,referencedColumnName =UUID)},
inverseJoinColumns = { b $ b public Set< Device> getParents(){
返回父母;
}

...
}

当我保存这样一棵树时:

 设备grandGrandPa = new Device(); 
grandGrandPa.setName(TEST+ counter +_grandGrandPa);

设备grandPa =新设备();
grandPa.setName(TEST+ counter +_grandPa);

grandGrandPa.addChild(grandPa);

Device daddy = new Device();
daddy.setName(TEST+ counter +_daddy);

grandPa.addChild(daddy);

Device son = new Device();
son.setName(TEST+ counter +_son);

daddy.addChild(儿子);
grandGrandPa = deviceService.register(grandGrandPa);

注册方法是递归的,它使用children列来下降树。当其保存grandPa的轮到weblogic返回一个异常时:


引起:org.hibernate.TransientObjectException:object引用未保存的瞬态实例 - 在刷新之前保存瞬态实例

我无法理解为什么会发生这种情况。在代码中父代Device上有一些查询时,它给了我这个错误:首先把它变成空的,然后把它变成一个值。
我使用weblogic 12.1.3和hibernate 4.0.0作为数据库Oracle 11g。

解决方案


在代码中存在父设备上的一些查询时,它给了我这个错误


默认情况下,Hibernate会刷新pending在尝试执行查询之前更改数据库。在那个阶段,所有关系中引用的所有实体应该已被保留,否则将引发异常。

另外,由于 mappedBy 是在 children 结束时,父母是关系的主角。因此,Hibernate会在持续时间完全忽略 children ,并在 parents 中查找临时实体。因此,您的坚持逻辑应该颠倒 - 先保存父母,最后保留孩子(或者,您可以简单地声明子女拥有方)。

I have an Entity that has two relation manyToMany with itself and I don't want to use Cascade.MERGE because I need to do some data checks to validate the data:

@Entity("device")
public class Device {
...
@ManyToMany(mappedBy = "parents", targetEntity = Device.class, fetch = FetchType.LAZY)
    public Set<Device> getChildren() {
        return this.children;
    }

    @Override
    @ManyToMany(targetEntity = Device.class, fetch = FetchType.LAZY)
    @JoinTable(name = "dem_hierarchy", joinColumns = {
        @JoinColumn(name = "CHILDREN_UUID", referencedColumnName = "UUID")},
            inverseJoinColumns = {
                @JoinColumn(name = "DEM_DEVICE_UUID", referencedColumnName = "UUID")})
    public Set<Device> getParents() {
        return parents;
    }

...
}

When I save a tree like this:

Device grandGrandPa = new Device();
grandGrandPa.setName("TEST" + counter + "_grandGrandPa");

Device grandPa = new Device();
grandPa.setName("TEST" + counter + "_grandPa");

grandGrandPa.addChild(grandPa);

Device daddy = new Device();
daddy.setName("TEST" + counter + "_daddy");

grandPa.addChild(daddy);

Device son = new Device();
son.setName("TEST" + counter + "_son");

daddy.addChild(son);
grandGrandPa = deviceService.register(grandGrandPa);

The register method is recursive and it descends the tree using the children column. When its the turn of the "grandPa" to be saved the weblogic return an exception:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

I cannot understand why this happens. It gives me this error when in code there are some queries on parent Device: first turn it is empty, second turn it has one value. I'm using weblogic 12.1.3 and hibernate 4.0.0, as database Oracle 11g.

解决方案

It gives me this error when in code there are some queries on parent Device

By default, Hibernate will flush pending changes to the database before attempting to execute a query. At that stage, all entities referenced in all relationships should have been persisted, or else an exception will be thrown.

Also, since mappedBy is declared on the children end, the parents is the owning side of the relationship. Because of that, Hibernate will ignore children completely at persist time and look for transient entities in parents instead. Your persisting logic should therefore be reversed - save parents first, children last (alternatively, you could simply declare children the owning side).

这篇关于JPA:在同一个实体上关联manyToMany的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆