Spring LazyInitializationException和@Transactional不工作

Spring LazyInitializationException和@Transactional不工作,spring,hibernate,jpa,Spring,Hibernate,Jpa,我正在使用Spring3.2.9,它的多层体系结构设计分解为3个模块:web、服务、存储库。在存储库中,我定义了一个通用DAO类,由其他特定于实体的DAO类继承 问题是,当我尝试从服务层延迟获取实体集合时,我总是得到LazyInitializationException。我曾尝试在我的服务类中添加@Transactional,但似乎不起作用。只有在DAO类方法中立即初始化所有惰性集合(并且仅在使用@Transactional注释DAO类时),我才能避免异常,但我只想在业务逻辑中需要这些集合时获取

我正在使用Spring3.2.9,它的多层体系结构设计分解为3个模块:web、服务、存储库。在存储库中,我定义了一个通用DAO类,由其他特定于实体的DAO类继承

问题是,当我尝试从服务层延迟获取实体集合时,我总是得到LazyInitializationException。我曾尝试在我的服务类中添加@Transactional,但似乎不起作用。只有在DAO类方法中立即初始化所有惰性集合(并且仅在使用@Transactional注释DAO类时),我才能避免异常,但我只想在业务逻辑中需要这些集合时获取它们,而不是提前获取它们

奇怪的是@Transactional只在DAO层工作,而不在服务层工作,应该在服务层使用它。我找到了解决这个问题的两种方法,但我对真正不尊重和解决这个问题感兴趣,不仅仅是让代码工作

存储库模块:

@Repository
public abstract class GenericDao<T> {

    protected Class<T> entityClass;

    @PersistenceContext
    protected EntityManager entityManager;

    .........

    public T findById(long id) {
        T entity = entityManager.find(entityClass, id);
        if (entity == null) {
            throw new EntityNotFoundException(entityClass.getSimpleName(), id);
        }

        return entity;
    }
}
DTO构造函数尝试访问user.getTeams(),然后发生异常。取而代之的是,应该通过对DB的额外查询来获取集合

配置:

存储库配置: ……其他一些配置,如数据源

<!--EntityManagerFactory-->
<bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.dialect" value="${hibernate_dialect}"/>
            <entry key="hibernate.hbm2ddl.auto" value="${hibernate_Hbm2ddlAuto}"/>
            <entry key="hibernate.show_sql" value="${hibernate_showSql}"/>
            <entry key="hibernate.format_sql" value="${hibernate_formatSql}"/>
        </map>
    </property>
</bean>

persistence.xml:

<persistence-unit name="persistenceUnit">
    ...other classes..
    <class>com.example.entity.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
    </properties>
</persistence-unit>

…其他类。。
com.example.entity.User
真的
服务配置:

<import resource="classpath*:META-INF/repositoryApplicationContext.xml"/>

<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

看起来用户和他或她的团队之间的@OneToMany关联是惰性加载的。当您将它们分配给Dto时,它仍然是代理而不是真实的集合。在那里放置一个断点,并在调试模式下查看它。记住任何请求(组建一个团队或其规模,使其充满活力)。一种方法是在查询中获取它们,但是

entityManager.find(entityClass, id)
没有选择权。你可以用

Hibernate.initialize(user.getTeams())

它看起来像是用户和他或她的团队之间的@OneToMany关联,是惰性加载的。当您将它们分配给Dto时,它仍然是代理而不是真实的集合。在那里放置一个断点,并在调试模式下查看它。记住任何请求(组建一个团队或其规模,使其充满活力)。一种方法是在查询中获取它们,但是

entityManager.find(entityClass, id)
没有选择权。你可以用

Hibernate.initialize(user.getTeams())

经过几天的头痛,我找到了答案。 我不得不搬家:

<import resource="classpath*:META-INF/repositoryApplicationContext.xml"/>
<tx:annotation-driven/>

从repositoryConfiguration.xml到dispatcher-servlet.xml,因为这是父Spring上下文


谢谢你的帮助。

在头痛几天后找到了答案。 我不得不搬家:

<import resource="classpath*:META-INF/repositoryApplicationContext.xml"/>
<tx:annotation-driven/>

从repositoryConfiguration.xml到dispatcher-servlet.xml,因为这是父Spring上下文


谢谢您的帮助。

检查配置。看:试试看this@AlanHay谢谢,我在那里找到了答案。@user1601401我的配置中已经有了答案,但不是在正确的xml中。请检查配置。看:试试看this@AlanHay谢谢,我在那里找到了答案。@user1601401我的配置中已经有了,但不是正确的xml。是的,我知道,这与调用getTeams().size()是一样的。无论如何,谢谢。我知道这与调用getTeams().size()是一样的。谢谢你