即使在 HQL 查询中使用 Join Fetch,Hibernate Lazy Initialization 异常

Hibernate Lazy Initialization exception even using Join Fetch in HQL queries

我想用延迟获取模式初始化一个集合并在我的查询中使用 Join Fetch 但我有时(并非总是)遇到延迟初始化异常 ???

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: xxx.entity.Product.producerEntities, could not initilaize proxy - no session ...

例如这个查询:

"select p from Product p left join fetch p.producerEntities"

还有我的坚持class:

    class Product
    {
        Set<Producer> producerEntities = new HashSet<>();
        ....
        @OneToMany(fetch = FetchType.LAZY)
        @JoinColumn(name="pid")
        public Set<Producer> getProducerEntities(){
         return producerEntities;
         }
    ....

}

我不明白这是什么问题?

如果 join fetch 抛出 LIEX,那么我建议使用动态实体图,因为如果您需要定义用例特定图。

让我们试试这个,我做了并且为我工作。

public class DynamicEntityGraphDemo {

    public static void main(String[] args) {

        EntityManager em = HibernateUtil.getEntityManager();
        EntityGraph graph = em.createEntityGraph(Product.class);
        Subgraph itemGraph = graph.addSubgraph("producerEntities");

        Map hints = new HashMap();
        hints.put("javax.persistence.loadgraph", graph);

        Product pro = em.find(Product.class, 1, hints);
        System.out.println("DynamicEntityGraphDemo pro  = " + pro.toString() + 
                 "producer =  " + pro.getProducerEntities().toString());
    }
}

注意:动态实体图在检索子实体时使用 LEFT OUTER JOIN。 (子图 itemGraph = graph.addSubgraph("producerEntities");)

加入获取p.producerEntities,而不是p.producer..

问题出在我的集合 setter 和 getter 方法名称中。解决了。​​

解决的方法很多,利用hibernate属性

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
    return dataSource;
}

@Bean
public LocalSessionFactoryBean getSessionFactory() throws IOException {
    LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
    factoryBean.setDataSource(dataSource()); 

    Properties hibernateProperties = new Properties(); 
    hibernateProperties.setProperty("hibernate.enable_lazy_load_no_trans", "true"); 
    factoryBean.setHibernateProperties(hibernateProperties);
    factoryBean.afterPropertiesSet();

    return factoryBean;
}

@Bean
public HibernateTransactionManager getTransactionManager() throws IOException {
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();
    transactionManager.setSessionFactory(getSessionFactory().getObject());
    return transactionManager;
}

或者您可以使用

org.hibernate.annotations.@Proxy 

@Entity
@Table(name = "ACTOR")
@Proxy(lazy = false)
public class Actor