【问题标题】:Hibernate session to stay open to retreive the many to one POJO休眠会话保持开放以检索多对一 POJO
【发布时间】:2020-02-29 10:45:49
【问题描述】:

我有 2 个 POJO、Event 和 OrganizerProfile。他们的关系是多对一的。 如果我从数据库中检索事件,则 OrganizerProfile 在调试器中显示为空,而不是它应该是什么。另外,我必须让休眠会话保持打开状态才能调用 event.getOrganizerProfile。

如果我得到事件,关闭休眠会话,那么事件中的OrganizerProfile 将无法检索。

        new EventDTO(this.getEvtByDateAddress(_event.getDate(), _event.getAddress(), /*dont close sess*/false));

你能解释一下吗?

谢谢

<hibernate-mapping package="com.example.client.serializable">
   <class name="Event" table="event">
   <id name="oid" type="long" column="oid">
     <generator class="increment">
        <param name="initial_value">1</param>
     </generator>
  </id>
  <property name="evtName">
     <column name="evtName"/>
  </property>
  <property name="address">
     <column name="address"/>
  </property>
  <property name="date" type="date">
     <column name="date"/>   
  </property> 
  <many-to-one name="organizerProfile" cascade="all"></many-to-one>
</class>
</hibernate-mapping>

<hibernate-mapping package="com.example.client.serializable">
<class name="OrganizerProfile" table="organizerprofile">
  <id column="oid" name="oid" type="long">
  <generator class="increment">
    <param name="initial_value">1</param>
  </generator>
  </id>
  <property generated="never" lazy="false" name="acctOid">
    <column name="acctOid"/>
  </property>
  <property generated="never" lazy="false" name="email">
    <column name="email"/>
  </property>
  <property generated="never" lazy="false" name="name">
    <column name="name"/>
  </property>
  <property generated="never" lazy="false" name="contact">
    <column length="5120" name="contact"/>
  </property>
  <property name="profilePicName">
    <column name="profilePicName"/>
  </property>
</class>
</hibernate-mapping>

public Event getEvtByDateAddress(Date _date, String _address, boolean _closeSess)
{
    try
    {
        if(!session.isOpen())
        {
            session = HibernateUtil.getSessionFactory().openSession();
        }
        session.beginTransaction();
        Criteria criteria = session.createCriteria(Event.class);
        criteria.add(Restrictions.eq("date", _date));
        criteria.add(Restrictions.eq("address", _address));
        Event evt = (Event)criteria.uniqueResult();
        if(_closeSess)
        {
            session.close();
        }
        if (evt==null)
        {
            LogUtils.logInfo("The event does not exist: " + _date + " " + _address);
            return null;
        }
        else
        {
            return evt;
        }
    }
    catch(Exception e)
    {
        LogUtils.logInfo(e.toString());
        if(_closeSess)
        {
            session.close();
        }
        return null;
    }
}

public EventDTO(Event _event)
{
    this.oid=_event.getOid();
    this.evtName=_event.getEvtName();
    this.address=_event.getAddress();
    this.date=_event.getDate();
    this.evtPicName=_event.getEvtPicName();
    this.organizerProfile=new OrganizerProfileDTO(_event.getOrganizerProfile());
}

【问题讨论】:

    标签: java hibernate one-to-many


    【解决方案1】:

    &lt;many-to-one name="organizerProfile" cascade="all"&gt;&lt;/many-to-one&gt;

    由于您没有在多对一映射中指定属性lazy,因此关联实体将被代理(请参阅hibernate mapping documentation point 12),因此不会获取您的相关实体并且无法在会话之外访问,在会话内部你可以访问它,因为当你尝试访问它时,hibernate 会自动获取它。

    如果你想在会话之外访问相关实体,你必须手动获取它,让 hibernate 初始化它 - 在会话中 - 或者你可以将你的获取类型设置为渴望 (&lt;many-to-one name="organizerProfile" cascade="all" lazy="false"&gt;&lt;/many-to-one&gt;),我不会推荐(N+1 selects Problem)。

    使用您的代码手动获取的示例:

    Criteria criteria = session.createCriteria(Event.class);
    criteria.setFetchMode("organizerProfile", FetchMode.JOIN);
    criteria.add(Restrictions.eq("date", _date));
    criteria.add(Restrictions.eq("address", _address));
    

    阅读也可能有帮助:Hibernate 4.3 docs #20: Performance fetching

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      • 2012-06-29
      • 1970-01-01
      • 2018-01-11
      相关资源
      最近更新 更多