Hibernate session to stay open to retreive the many to one POJO

Ming Leung :

I have 2 POJO, Event and OrganizerProfile. Their relationship are many to one. If I retrieve the Event from database, the OrganizerProfile is showing as empty from the debugger instead of what it should be. Also, I have to leave the hibernate session open to call the event.getOrganizerProfile.

If I get the Event, close the hibernate session, then the OrganizerProfile in the Event cannot be retrieved.

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

Can you please explain this?

Thanks

<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());
}
PaulD :

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

Since you did not specify the property lazy in your many-to-one mapping, the associated entities will be proxied (see hibernate mapping documentation point 12) thus your related entity is not fetched and cannot be accessed outside of the session, inside of the session you can access it, because hibernate will automatically fetch it when you try to access it.

If you want to access the related entity outside of the session you have to fetch it manually, let hibernate initialize it - both within the session - or you can set your fetch type to eager ( <many-to-one name="organizerProfile" cascade="all" lazy="false"></many-to-one>) which I would NOT recommend (N+1 selects Problem).

Example of manual fetching with your code:

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

Also possibly helpful to read: Hibernate 4.3 docs #20: Performance fetching

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=21376&siteId=1