[英]Spring 4 hibernate 4 JPA LazyInitializationException: failed to lazily initialize a collection of role
I made a database connection with spring 4 used with hibernate 4 and JPA. 我与Spring 4和Hibernate 4和JPA一起使用建立了数据库连接。 When I try to get a lazy initializated field I got an LazyInitializationException. 当我尝试获取懒惰的初始化字段时,出现LazyInitializationException。
My applicationContext.xml: 我的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"/>
Model: 模型:
@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;
...
I found only MVC filter solution, but I don't use MVC. 我只找到了MVC过滤器解决方案,但没有使用MVC。 I tried Hibernate.initialize(...) and @Transational, @Fetch annotations but these didn't solved my problem. 我尝试了Hibernate.initialize(...)和@ Transational,@ Fetch批注,但是这些并没有解决我的问题。
Here is the stacktrace: 这是堆栈跟踪:
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 is right, you are using a proxy managed by Hibernate in some location in your code which is outside a transactional context. Guillaume是正确的,您在代码中某个位于事务上下文之外的位置中使用了Hibernate管理的代理。
Because of that, when you call getLegitimacies()
that has not been initialized yet, Hibernate try to populate its proxy by graping a session and make a database call. 因此,当您调用尚未初始化的getLegitimacies()
,Hibernate会尝试通过抓取会话并进行数据库调用来填充其代理。
If you are in a controller for example and no session is available, an exception is thrown. 例如,如果您在控制器中并且没有会话可用,则会引发异常。 You have to fetch your legitimacies set at some point in your dao (by using FETCH keyword in your HQL query for example) : 您必须在dao的某个位置获取合法性设置(例如,通过在HQL查询中使用FETCH关键字):
FROM Employee e LEFT JOIN FETCH e.legitimacies WHERE <your_predicate>;
You should also not manipulate your entities if not in service/dao layer but use a DTO instead to avoid those problems. 如果不在服务/传输层中,则也不应操作实体,而应使用DTO以避免这些问题。
Lazy exceptions occurs when you try to access a referenced object outside of the original session. 当您尝试在原始会话之外访问引用的对象时,就会发生惰性异常。
Basically, you are doing this : 基本上,您正在这样做:
* Open a session
* Fetch an object, let's say X
* Close the session
* Try to access X.getY()
A solution is to fetch X and Y at the same time, while the session is open. 一种解决方案是在会话打开时同时获取X和Y。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.