1

这是我卡住的地方:

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”是一个简单的普通实体,具有一对字符串属性。

我有一个“编辑”jsf 页面,它通过 id 加载“TipoCaratteristica”并尝试在标签中显示其列表。

我使用 ejb-facade 方法来获取已编辑的对象:

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

然后,在 jsf 支持 bean 中:

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

我读了一些关于那个例外的东西。实际上,在“traduzioni”集合上设置获取类型 EAGER 可以修复它,但我不想这样做。我读过关于在事务中完成所有操作,或使用 Hibernate.initialize() 但不知道如何做到这一点。

你能帮我吗?

4

2 回答 2

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
于 2012-05-14T08:38:53.717 回答
2

PersistentContext.EXTENDED您可以使用实体管理器中的属性来解决此问题。

例子:

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

或在较新的版本中:

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

发生此错误是因为对于每个事务,实体管理器事务都关闭,此属性避免了这种情况并允许实体管理器保持可用。您可以阅读 Dan Allen 的 Seam in Action 一书了解更多详细信息,他详细解释了这个问题。

于 2012-06-28T21:17:14.847 回答