2012-05-14 7 views
1

Вот где я застрял:Java EE 6 исключение нагрузки + Hibernate Ленивый

javax.servlet.ServletException: org.hibernate.LazyInitializationException: не удалось инициализировать лениво коллекцию роли: it.trew .model.TipoCaratteristica.traduzioni, не сессия или сессия была закрыта

Некоторые из моих сущностей кода:

@Entity 
@Table(name = "tipi_caratteristiche") 
public class TipoCaratteristica implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id") 
    private Long id; 

    private String nome; 

    @OneToMany(cascade = CascadeType.ALL) 
    @JoinTable(
     name = "tipi_caratteristiche_traduzioni", 
     joinColumns = { @JoinColumn(name = "tipo_caratteristica_id") }, 
     inverseJoinColumns = { @JoinColumn(name = "traduzione_id") } 
    ) 
    private List<Traduzione> traduzioni = new ArrayList<Traduzione>(); 

«Traduzione» - простой простой объект с парой свойств String.

У меня есть страница «edit» jsf, которая загружает «TipoCaratteristica» по id и пытается показать свой список в теге.

Я использую метод EJB-фасад для извлечения редактируемого объекта:

public T find(Object id) { 
     return getEntityManager().find(entityClass, id); 
    } 

Затем в JSF основы боба:

TipoCaratteristica tc = ejbFacade.find(Long.valueOf(value)); 

Я читал кое-что об этом исключением. Фактически, установка типа EACHER в коллекции «traduzioni» исправить, но я не хочу. Я читал о том, как делать все транзакции или использовать Hibernate.initialize(), но не знаю, как это сделать.

Вы можете мне помочь?

ответ

2
@Override 
public TipoCaratteristica find(Object id) { 
    TipoCaratteristica result = super.find(id); 
    Hibernate.initialize(result.getTraduzioni()); 
    return result; 
} 

Или вместо того, чтобы использовать em.find(), использовать запрос, который будет загружать все один запрос:

select distinct tc from TipoCaratteristica 
left join fetch tc.traduzioni 
where tc.id = :id 
+1

У вас, похоже, есть базовый параметризованный класс для ваших фасадов EJB и один подкласс этого фасада EJB для каждого объекта. Вышеупомянутый переопределенный метод должен быть в фасаде EJB для объекта TipoCaratteristica. Если мои предположения ошибочны, отправьте свой код. –

+0

ОК. Я должен помнить, что initialize() должен выполняться внутри EJB-методов, не так ли? –

+0

Это должно быть сделано в месте, где сеанс все еще открыт, внутри транзакции. Если вы сделаете это, как только сессия будет закрыта, вы, очевидно, получите такое же ленивое исключение загрузки. –

2

Вы могли бы решить это с помощью PersistentContext.EXTENDED атрибута в менеджере сущностей.

Пример:

@PersistentContext(type=PersistentContext.EXTENDED) 
private EntityManager em; 

или в более новых версиях:

@PersistentContext(type=PersistentContextType.EXTENDED) 
private EntityManager em; 

Эта ошибка происходит потому, что для каждой операции транзакция менеджера объект закрыта, этот атрибут позволяет избежать этого и позволяет менеджер объекта проживание доступно , Вы можете прочитать более подробно, прочитав «Шов в книге действий» Дэн Аллен, он подробно объясняет эту проблему.