java - Spring 4 hibernate 4 JPA LazyInitializationException : failed to lazily initialize a collection of role

标签 java spring hibernate jpa lazy-initialization

我使用 spring 4 与 hibernate 4 和 JPA 建立了数据库连接。当我尝试获取延迟初始化字段时,我收到了 LazyInitializationException。

我的applicationContext.xml:

<context:annotation-config />
<context:component-scan base-package="xy" />

<jpa:repositories base-package="xy.repositories" />

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="punit" />
    <property name="dataSource" ref="dataSource" />

    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" />
        </bean>
    </property>
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
            <entry key="hibernate.hbm2ddl.auto" value="update" />
            <entry key="hibernate.format_sql" value="true" />
        </map>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />

</bean>


<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/keysystem" />
    <property name="username" value="username" />
    <property name="password" value="password" />
</bean>

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

型号:

@Entity
@Table
public class Employee {
    @Id
    @GeneratedValue
    private long employeeId;
    private String firstName;
    private String lastName;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "employee")
    @Cascade(CascadeType.ALL)
    @Fetch(FetchMode.SELECT)
    private Set<Legitimacy> legitimacies;
    ...

我只找到了MVC过滤器解决方案,但我不使用MVC。我尝试了 Hibernate.initialize(...) 和 @Transational、@Fetch 注释,但这些并没有解决我的问题。

这是堆栈跟踪:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: xy.Employee.legitimacies, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180)
    ... 64 more

最佳答案

Guillaume 是对的,您在代码中位于事务上下文之外的某个位置使用了由 Hibernate 管理的代理。

因此,当您调用尚未初始化的 getLegitimacies() 时,Hibernate 会尝试通过抓取 session 来填充其代理并进行数据库调用。

例如,如果您位于 Controller 中并且没有可用的 session ,则会引发异常。您必须在 dao 中的某个点获取合法性设置(例如,通过在 HQL 查询中使用 FETCH 关键字):

FROM Employee e LEFT JOIN FETCH e.legitimacies WHERE <your_predicate>;

如果不在 service/dao 层中,您也不应该操作您的实体,而是使用 DTO 来避免这些问题。

关于java - Spring 4 hibernate 4 JPA LazyInitializationException : failed to lazily initialize a collection of role,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33848632/

相关文章:

java - 什么时候应该使用@Component 而不是@Service?

json - 通过动态 @JsonIgnore 注释按需延迟加载

java - 提前检测字符串超长

java - 以不同模式运行应用程序

java - 在唯一约束 JPA/Hibernate 期间添加自定义错误消息的更好方法

java - 尝试使用 Erwin Vervaet 的框架存储临时集合并获取 ClassCastException

Java .class 文件结构 - InnerClasses 属性

java - 构造函数中可覆盖的方法调用有什么问题?

java - 如何知道 Android 上的应用/游戏是否通过通知启动?

java - 如何显示primefaces布局的镜像