Hibernate сеанс, чтобы оставаться открытым, чтобы получить множество к одному POJO - PullRequest
1 голос
/ 29 февраля 2020

У меня есть 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());
}

1 Ответ

1 голос
/ 02 марта 2020

<many-to-one name="organizerProfile" cascade="all"></many-to-one>

Поскольку вы не указали свойство lazy в своем сопоставлении "многие к одному", связанные сущности будут проксированы (см. документация по отображению спящего режима 12 ) поэтому ваша связанная сущность не извлекается и не может быть доступна вне сеанса, внутри сеанса вы можете получить к ней доступ, потому что hibernate автоматически получит ее при попытке доступа к ней.

Если вы хотите получить доступ связанный объект вне сеанса, вы должны получить его вручную, позволить hibernate инициализировать его - оба в сеансе - или вы можете установить свой тип выборки на eager (<many-to-one name="organizerProfile" cascade="all" lazy="false"></many-to-one>), который я НЕ рекомендовал бы ( N + 1) выбирает Проблема ).

Пример ручной выборки с вашим кодом:

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 документы # 20: Выбор производительности

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...