Учитывая следующее отображение
<class name="com.domain.Season" table="cm.pub.jsn_mstr">
<id name="seasonCode" column="season_code" length="1"/>
<property name="name" type="string" column="name" length="20"/>
<set name="promotions" lazy="false">
<key column="season_code"/>
<one-to-many class="com.domain.Promotion" not-found="ignore"/>
</set>
</class>
Как я могу включить или исключить нагрузку promotions
? Я мог бы использовать lazy="true"
, хотя я использую Джексона для сериализации результата, который происходит после закрытия сессии.
public Collection<Season> getSeasons(boolean withPromotions) {
final Session session = sessionFactory.getCurrentSession();
try {
session.beginTransaction();
return (List<Season>) session.createQuery("from Season s").list();
} finally {
session.getTransaction().commit();
}
}
ОБНОВЛЕНИЕ : проблема с отложенной загрузкой.
Метод getSeasons
, описанный выше, используется в контроллере MVC, который будет извлекать сезоны, а затем с помощью Джексона сериализовать их в JSON (используя средство разрешения представления Spring / MVC), поэтому я на самом деле не получаю доступ к объектам сам, поэтому любая попытка ленивая загрузка коллекции приводит к исключению (поскольку Джексон вызовет итератор для всех свойств коллекции).
Вот пример, показывающий, что будет сгенерировано исключение:
public Collection<Season> getSeasons(boolean withPromotions) {
final Session session = sessionFactory.getCurrentSession();
final List<Season> r;
try {
session.beginTransaction();
r = (List<Season>) session.createQuery(
withPromotions
? "from Season s join fetch s.promotions"
: "from Season s"
).list();
} finally {
session.getTransaction().commit();
}
try {
for (Season s : r) {
for (Promotion p : s.getPromotions()) {
// Exception thrown here as we attempted to get an iterator.
LOG.debug("Promotion: " + p.getName());
}
}
} catch (Exception ex) {
LOG.error("Couldn't get promotions", ex);
}
return r;
}
И, конечно, на этот раз отображение должно иметь lazy="true"
, иначе оно всегда будет стремиться прочитать коллекцию.
<class name="com.domain.Season" table="cm.pub.jsn_mstr">
<id name="seasonCode" column="jsn_seas" length="1"/>
<set name="promotions" lazy="true">
<key column="jpr_seas"/>
<one-to-many class="com.domain.Promotion" not-found="ignore"/>
</set>
</class>
Тип данных для поля promotions
: Collection<Promotion>
.