我有2个POJO,事件和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());
}
<many-to-one name="organizerProfile" cascade="all"></many-to-one>
由于您没有在多对一映射中指定属性lazy
,因此将对关联实体进行代理(请参见hibernate mapping documentation point 12),因此不会获取相关实体,并且无法在会话外部,内部访问您可以访问它的会话,因为当您尝试访问它时,休眠将自动获取它。
[如果要在会话外部访问相关实体,则必须手动获取它,让休眠在会话中都对其进行初始化-或者可以将获取类型设置为渴望(<many-to-one name="organizerProfile" cascade="all" lazy="false"></many-to-one>
),我不建议这样做(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));