如何获取 @OneToMany 和 @ManyToMany 实体

Posted

技术标签:

【中文标题】如何获取 @OneToMany 和 @ManyToMany 实体【英文标题】:How to Fetch @OneToMany and @ManyToMany Entities 【发布时间】:2011-07-27 07:08:21 【问题描述】:

我的问题与以下内容非常相关:Why am I getting a Hibernate LazyInitializationException in this Spring MVC web application when the data displays correctly?

我在特定实体上具有以下属性:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
@JoinColumn(referencedColumnName = "id", name = "ID_FORMAT_FILE")
private List<ColumnFormat> columnList;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "FILEFORMAT_ORIGINATOR", joinColumns = @JoinColumn(name =   "FILEFORMAT_ID", referencedColumnName = "id")
    , inverseJoinColumns = @JoinColumn(name = "ORIGINATOR_ID", referencedColumnName = "id"))
private List<Originator> originators;  

您可能已经注意到,我在这两个关系上都有一个 Eager Fetch 类型,但它给出了以下内容:

Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
    at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:119)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:71)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:54)
    at org.hibernate.loader.entity.BatchingEntityLoader.createBatchingEntityLoader(BatchingEntityLoader.java:133)
    at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:1914)
    at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:1937)
    at org.hibernate.persister.entity.AbstractEntityPersister.createLoaders(AbstractEntityPersister.java:3205)
    at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:3191)
    at org.hibernate.persister.entity.SingleTableEntityPersister.postInstantiate(SingleTableEntityPersister.java:728)
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:348)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:902)
    ... 33 more  

我必须访问不同 bean 上的两个列表 List&lt;ColumnFormat&gt; columnListList&lt;Originator&gt; originators,但如果两者都是 Fetch Type Eager 我会遇到上述问题,如果一个其中懒惰我得到以下信息:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: xxx.xxx.xxx.xxx.FileFormat.originators, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
    at org.hibernate.collection.AbstractPersistentCollection.readElementExistence(AbstractPersistentCollection.java:157)
    at org.hibernate.collection.PersistentBag.contains(PersistentBag.java:262)
    at java.util.ArrayList.batchRemove(ArrayList.java:632)
    at java.util.ArrayList.removeAll(ArrayList.java:605)
    at xxx.xxx.xxx.xxx.bean.FileFormatEdit.init(FileFormatEdit.java:1040)
    ... 75 more  

有没有办法在不出现这些问题的情况下检索不同 bean 上的列表?

【问题讨论】:

你能发布一些你用来检索数据的代码吗? 可以在这里找到答案:Hibernate cannot simultaneously fetch multiple bags 【参考方案1】:

以前没遇到过这个问题,只是在 Hibernate 论坛上搜索“无法同时获取多个包”返回 this link。

该链接中的blog posts 之一可能包含您正在寻找的解决方案。

【讨论】:

您提供的链接肯定有帮助。谢谢,仍在研究解决方案 我会接受你的回答,因为它解决了我提出的实际问题,但是考虑到新的要求,我不得不以不同的方式解决它。【参考方案2】:

我删除了所有fetch=FetchType.EAGER 并且它工作正常。我正在使用 Hibernate 3.5.6-Final、Spring 3.0.4 和 Junit 4。我认为 fetch-EAGER 是默认设置,因为我的对象会加载所有子对象。

这是会话工厂:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
    p:dataSource-ref="dataSource"
    p:packagesToScan="org.pfc.modelo">

    <property name="hibernateProperties">
        <props>
            <prop key="dialect">org.hibernate.dialect.Oracle10gDialect</prop>
            <prop key="show_sql">true</prop>
            <prop key="format_sql">true</prop>
        </props>
    </property>
</bean>

这是类:

@Entity
@Table(name="D_ACTIVIDAD")
public class Actividad implements Serializable 


private static final long serialVersionUID = 1L;

@Id
@SequenceGenerator(sequenceName="SQ_ACTIVIDAD",name="seqActividad")
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="seqActividad")
private Integer idActividad;

@Column(name="FECHA",nullable=false)
@Temporal(TemporalType.TIMESTAMP)
private Calendar fecha;

@Column(name="TITULO",nullable=false)
private String titulo;

@Column(name="TEXTO",nullable=false)
private String texto;

@ManyToOne
@JoinColumn(name="IDASOCIACION")
private Asociacion asociacion;

@OneToMany(mappedBy="actividad",cascade=CascadeType.ALL,orphanRemoval=true)
private List<ComentarioActividad> comentarios;

@OneToMany(mappedBy="actividad",cascade=CascadeType.ALL,orphanRemoval=true)
@OrderBy(value="fecha")
private List<Documento> documentos;

     //set and get methods 
     ...........
     ...........
     ...........

   

【讨论】:

以上是关于如何获取 @OneToMany 和 @ManyToMany 实体的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2.8 表单 CollectionType 字段 manyTo many

从 ManyToOne 获取 OneToMany 关联

在 Hibernate 双向 ManytoOne、OnetoMany 的映射列中获取 null

Hibernate @OneToMany Mapping 获取记录

我想禁用实体@OneToMany 中的获取

加入获取嵌套在 @OneToMany 中的 @ManyToOne