Hibernate不能同时为Parent-Children-Grandchildren单向关联提取多个包

时间:2015-09-15 12:18:52

标签: collections

直截了当。我获得了Hibernate异常Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

我有Parent --(1-*)--> Child --(1-*)--> Grandchild单向关系中的3个实体:

NetworkElement -> NetworkElementInterface -> NetworkElementInterfaceCounters

在这两种关系中我都定义了FetchType.LAZY

@Entity
@Table(name = "NETWORK_ELEMENTS")
public class NetworkElement extends Device {

    @Id
    @Column(name = "ID_DEVICE")
    private Long id;

    @ManyToOne(targetEntity = DeviceLocation.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_DEVICE_LOCATION")
    private DeviceLocation deviceLocation;

    @Column(name = "MODEL", length = 30)
    private String model;

    @Column(name = "TYPE", length = 30)
    private String type;

    @Column(name = "IMAGE", length = 50)
    private String image;

    @OneToMany(orphanRemoval = true, fetch = FetchType.LAZY, targetEntity = NetworkElementInterface.class, cascade=CascadeType.ALL)
    @Size(min = 0, max = 99)
    private List<NetworkElementInterface> interfaces;
}

@Entity
@Table(name = "NETWORK_ELEMENT_INTERFACES")
public class NetworkElementInterface {

    @Id
    @Column(name = "ID_NETWORK_ELEMENT_INTERFACES")
    protected Long id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "SPEED")
    private Long speed;

    @Column(name = "DUPLEX")
    private String duplex;

    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(name = "NETWORK_ELEMENT_INTERFACE_COUNTERS", joinColumns = @JoinColumn(name = "ID_NETWORK_ELEMENT_INTERFACE"))
    @Type(type = "com.netsuite.wind.entity.NetworkElementInterfaceCounters")
    private List<NetworkElementInterfaceCounters> interfaceCountersHistory;
}


@Embeddable
public class NetworkElementInterfaceCounters {

    private Long inputErrors;

    private Long inputDrops;

    private Long inputDiscards;

    private Long inputCRCErrors;

    private Long inputFifoErrors;

    private Long outputErros;

    private Long outputDrops;

    private Long outputCRCErrors;

    private Long outputFifoErrors;
}

我想要实现的目标是:

在我的DAO中

1)创建一个方法,该方法将Parent完全填充childrengrandchildren(NetworkElement -> NetworkElementInterface -> NetworkElementInterfaceCounters)

1b) (not really important here, just curious)最后,我还希望在我的children NetworkElement对象中填充其他类型的DeviceLocation以及填充的NetworkInterfaces

我的NetworkElement的DAO方法:

@Transactional()
@SuppressWarnings("unchecked")
public NetworkElement getByIdWithInterfaces(Long id) {
    final Session session = sessionFactory.getCurrentSession();

    ------------------------------------------------------        
    // This works well when I only want children to by populated
    Query query = session.createQuery("SELECT ne FROM NetworkElement ne JOIN FETCH ne.interfaces WHERE ne.id = :id");
    ------------------------------------------------------
    // This doesn't work when I also try to fetch grandchildren. I am given Hibernate exception: "cannot simultaneously fetch multiple bags"
    Query query = session.createQuery("SELECT ne FROM NetworkElement ne JOIN FETCH ne.interfaces nei JOIN FETCH nei.interfaceCountersHistory WHERE ne.id = :id");
    ------------------------------------------------------
    // Eventually I tried "FETCH ALL PROPERTIES" which also doesn't work.
    Query query = session.createQuery("FROM NetworkElement ne FETCH ALL PROPERTIES WHERE ne.id = :id");
    ------------------------------------------------------

    query.setParameter("id", id);

    NetworkElement result = null;

    try {
        result = (NetworkElement) query.uniqueResult();
    } catch (NoResultException e) {
        e.printStackTrace();
    }

    return result;
}

所以: 1) Query query = session.createQuery("SELECT ne FROM NetworkElement ne JOIN FETCH ne.interfaces nei JOIN FETCH nei.interfaceCountersHistory WHERE ne.id = :id"); 尽量让它发挥作用。

我认为我遗漏了一些注释,以避免这种异常。我注意到在一些例子中他们使用的是@IndexColumn,但是这个注释已被弃用。请注意这方面的任何说明。

0 个答案:

没有答案