org.hibernate.LazyInitializationException: 未能在另一个环境中延迟初始化 collection 角色
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role in another environment
美好的一天,
知道这个标题是关于堆栈溢出的,也有多种解决方案。
但是这个案例有点不同,我不知道应该从哪里继续排查。
在我的 BaseUser.java
实体 class 中,我有以下代码:
@SuppressWarnings("serial")
@MappedSuperclass
public abstract class BaseUser< T extends BasePasswordHistory > extends
AuditModel implements IDeletable, IEditable, UserProfile {
// some other code here...
@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "user")
@OrderBy("passwordHistoryId desc")
public Set< T > getPasswordHistories() {
return passwordHistories;
}
// some other code here...
}
下面是我在ManagerImpl
级别调用密码历史的部分代码,BaseUserManagerImpl.java
.
Set< T > histories = user.getPasswordHistories( );
for ( T history : histories ) { // exception at this line in another environment
}
BaseUserManagerImpl.java
仍然在同一个休眠事务下,因此,它能够加载 passwordHistory
object 甚至它的 lazy fetch
类型。 (如有错误请指正)
这些代码在原始环境中运行良好(我们将其命名为 env A
),直到我将相同的代码部署到另一个环境中(我们将其命名为 env B
),它会命中 LazyInitializationException
喜欢标题。
我查了下WAS的版本,发现版本有些不一样。
其实我不认为这些是命中异常的原因。但我真的不知道为什么相同的代码不能在不同的环境中工作。有什么我应该进一步检查的吗?
在这里我 post 我的堆栈跟踪:
2019-06-25 17:17:47.967 [WebContainer : 3] ERROR c.c.i.c.c.u.e.ExceptionHandler - [cvmaker123] - Exception occurred
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.cv.ibs.cib.support.entity.BankUser.passwordHistories, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at com.cv.ibs.cib.common.service.impl.BaseUserManagerImpl.verifyPasswordHistory(BaseUserManagerImpl.java:241) ~[com.cv.ibs.cib.jar:na]
at com.cv.ibs.cib.support.service.impl.BankUserManagerImpl.updatePassword(BankUserManagerImpl.java:288) ~[com.cv.ibs.cib.jar:na]
at com.cv.ibs.cib.support.service.impl.BankUserManagerImpl.updatePassword(BankUserManagerImpl.java:1) ~[com.cv.ibs.cib.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95) ~[na:1.7.0]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56) ~[na:1.7.0]
at java.lang.reflect.Method.invoke(Method.java:620) ~[na:2.6 (10-05-2016)]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at com.sun.proxy.$Proxy464.updatePassword(Unknown Source) ~[na:na]
at c.c.i.c.app.profile.command.ChangePasswordCommandHandler.execute(ChangePasswordCommandHandler.java:42) ~[com.cv.ibs.cib.jar:na]
以下为部分代码:
public class ChangePasswordCommandHandler implements
CommandHandler< ChangePasswordCommand, Integer > {
@Autowired
private UserManager userManager;
public Integer execute(ChangePasswordCommand command)
throws BaseException {
return userManager.updatePassword( user, command.getNewPassword( ),
command.isResetPWD( ) );
}
}
@Service
public class UserManagerImpl extends
BaseUserManagerImpl< User, PasswordHistory > implements
UserManager {
public int updatePassword(User user, String newPassword,
boolean isResetPWD) throws BaseException {
User entity = findById( user.getUserId( ) );
final String newHash = getNewPasswordHash( entity, newPassword );
entity = verifyPasswordHistory( entity, entity.getPassword( ),
newHash, isResetPWD );
return 1;
}
}
public abstract class BaseUserManagerImpl< T extends BaseUser< U >, U extends BasePasswordHistory >
extends BaseManagerImpl< T, Long > implements BaseUserManager< T, U >,
UserProfileService {
final protected T verifyPasswordHistory(final T user, String oldHash,
String newHash, boolean isResetPWD) {
final int reuseNo = getMaxPassowrdhistory( );
Set< U > histories = user.getPasswordHistories( );
for ( U history : histories ) { // exception at this line in another environment
}
}
}
请指教。
您的方法至少应该是事务性的,只读的。
top tour class or method.
上使用@Transactional 注解吗
终于我发现了这个案例的问题所在。该项目的 WAS Java SDK 指向 Java 1.7。但是,代码是使用 Java 1.6.
编译的
我在检查 WAS classloader
目录时发现了这个。将WAS Console中的Java SDK改成Java 1.7后,问题解决。
美好的一天,
知道这个标题是关于堆栈溢出的,也有多种解决方案。
但是这个案例有点不同,我不知道应该从哪里继续排查。
在我的 BaseUser.java
实体 class 中,我有以下代码:
@SuppressWarnings("serial")
@MappedSuperclass
public abstract class BaseUser< T extends BasePasswordHistory > extends
AuditModel implements IDeletable, IEditable, UserProfile {
// some other code here...
@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "user")
@OrderBy("passwordHistoryId desc")
public Set< T > getPasswordHistories() {
return passwordHistories;
}
// some other code here...
}
下面是我在ManagerImpl
级别调用密码历史的部分代码,BaseUserManagerImpl.java
.
Set< T > histories = user.getPasswordHistories( );
for ( T history : histories ) { // exception at this line in another environment
}
BaseUserManagerImpl.java
仍然在同一个休眠事务下,因此,它能够加载 passwordHistory
object 甚至它的 lazy fetch
类型。 (如有错误请指正)
这些代码在原始环境中运行良好(我们将其命名为 env A
),直到我将相同的代码部署到另一个环境中(我们将其命名为 env B
),它会命中 LazyInitializationException
喜欢标题。
我查了下WAS的版本,发现版本有些不一样。
其实我不认为这些是命中异常的原因。但我真的不知道为什么相同的代码不能在不同的环境中工作。有什么我应该进一步检查的吗?
在这里我 post 我的堆栈跟踪:
2019-06-25 17:17:47.967 [WebContainer : 3] ERROR c.c.i.c.c.u.e.ExceptionHandler - [cvmaker123] - Exception occurred
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.cv.ibs.cib.support.entity.BankUser.passwordHistories, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186) ~[hibernate-core-3.3.1.GA.jar:3.3.1.GA]
at com.cv.ibs.cib.common.service.impl.BaseUserManagerImpl.verifyPasswordHistory(BaseUserManagerImpl.java:241) ~[com.cv.ibs.cib.jar:na]
at com.cv.ibs.cib.support.service.impl.BankUserManagerImpl.updatePassword(BankUserManagerImpl.java:288) ~[com.cv.ibs.cib.jar:na]
at com.cv.ibs.cib.support.service.impl.BankUserManagerImpl.updatePassword(BankUserManagerImpl.java:1) ~[com.cv.ibs.cib.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95) ~[na:1.7.0]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56) ~[na:1.7.0]
at java.lang.reflect.Method.invoke(Method.java:620) ~[na:2.6 (10-05-2016)]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ~[org.springframework.aop-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at com.sun.proxy.$Proxy464.updatePassword(Unknown Source) ~[na:na]
at c.c.i.c.app.profile.command.ChangePasswordCommandHandler.execute(ChangePasswordCommandHandler.java:42) ~[com.cv.ibs.cib.jar:na]
以下为部分代码:
public class ChangePasswordCommandHandler implements
CommandHandler< ChangePasswordCommand, Integer > {
@Autowired
private UserManager userManager;
public Integer execute(ChangePasswordCommand command)
throws BaseException {
return userManager.updatePassword( user, command.getNewPassword( ),
command.isResetPWD( ) );
}
}
@Service
public class UserManagerImpl extends
BaseUserManagerImpl< User, PasswordHistory > implements
UserManager {
public int updatePassword(User user, String newPassword,
boolean isResetPWD) throws BaseException {
User entity = findById( user.getUserId( ) );
final String newHash = getNewPasswordHash( entity, newPassword );
entity = verifyPasswordHistory( entity, entity.getPassword( ),
newHash, isResetPWD );
return 1;
}
}
public abstract class BaseUserManagerImpl< T extends BaseUser< U >, U extends BasePasswordHistory >
extends BaseManagerImpl< T, Long > implements BaseUserManager< T, U >,
UserProfileService {
final protected T verifyPasswordHistory(final T user, String oldHash,
String newHash, boolean isResetPWD) {
final int reuseNo = getMaxPassowrdhistory( );
Set< U > histories = user.getPasswordHistories( );
for ( U history : histories ) { // exception at this line in another environment
}
}
}
请指教。
您的方法至少应该是事务性的,只读的。 top tour class or method.
上使用@Transactional 注解吗终于我发现了这个案例的问题所在。该项目的 WAS Java SDK 指向 Java 1.7。但是,代码是使用 Java 1.6.
编译的我在检查 WAS classloader
目录时发现了这个。将WAS Console中的Java SDK改成Java 1.7后,问题解决。