Java 使用Spring错误休眠一对多映射
我正在将Hibernate与Spring一起使用,遇到了以下问题未能懒洋洋地初始化集合:,没有会话或使用一对多关系关闭会话 我有两个表,一个是用户&来自用户的角色我正在尝试使用延迟获取来获取角色。 堆栈跟踪Java 使用Spring错误休眠一对多映射,java,spring,hibernate,session,Java,Spring,Hibernate,Session,我正在将Hibernate与Spring一起使用,遇到了以下问题未能懒洋洋地初始化集合:,没有会话或使用一对多关系关闭会话 我有两个表,一个是用户&来自用户的角色我正在尝试使用延迟获取来获取角色。 堆栈跟踪 org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.rep.users.KZ_Users.roleList, no session or sessio
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.rep.users.KZ_Users.roleList, no session or session was closed
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
org.hibernate.collection.PersistentList.iterator(PersistentList.java:115)
com.rep.users.KZ_Users.getAuthorities(KZ_Users.java:137)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.createSuccessAuthentication(AbstractUserDetailsAuthenticationProvider.java:186)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:165)
org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:120)
org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:48)
org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:138)
org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:48)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:97)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
我已经在我的KZ_Users pojo类中实现了UserDetails,可序列化
导致错误的方法是
@Override
public Collection<GrantedAuthority> getAuthorities() {
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
for (Roles roles : roleList) { //<-- ERROR
list.add(new GrantedAuthorityImpl(roles.getRole()));
}
return list;
}
提前感谢。将
Spring
特定的API与您的实体分开。不要在@实体
类中直接实现UserDetails
接口,而是对其进行扩展(或组合),即:
注意,通过这种方式,您将访问标记为my@Transactional的事务中的角色集合。现在Spring
可以在需要的地方调用getAuthorities()
,它可以正常工作,因为它已经初始化,不再需要连接到数据库
始终知道事务的开始和结束位置
根据您的用例,您可能还会考虑使用or(或本机Hibernate
APIOpenSessionInViewFilter/Intercetor
的等价物),但是
请告诉我,以班级的名义写的KZ
不是你的初始密码?如果是,请,请,请不要那样做…错误说明了一切。您正在访问未初始化的集合,并且会话已关闭。会话打开时强制初始化集合,或保持会话打开。您没有显示任何与会话管理相关的代码……是的,我知道了,但是方法getAuthorities()
是由Spring调用的,因此我不知道如何初始化它,也不知道在哪里初始化它。如果所有hibernate映射都不相关,请从帖子中删除它们。添加错误的完整堆栈跟踪,并解释如何调用该方法。在hibernate映射中,lazy=true。将其设为false,然后重试。@RizN81所以这个方法是在Spring
使用的bean中吗?简单,用@Transactional
注释并启用。感谢您的回答,是的KZ
不是我的首字母缩写,而是数据库的名称schema@Roadrunner我也有同样的问题。我尝试了你在回答中的建议,但我仍然有同样的例外。我的@SebastianDuque就是要知道事务的边界,知道Hibernate延迟加载是如何工作的;i、 e.在您的代码行中,27将不会获取角色列表;您必须通过它进行迭代才能加载它;我可以假设您不是在userdetailsiml
构造函数中初始化reoles,而是在事务关闭之后;但我必须看到完整的堆栈跟踪才能知道这一点@Roadrunner是的,刚刚成为UserDetailsServiceImpl组件,事务作用域现在是整个loadUserByUsername()方法。多谢各位。
16:15:01,317 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/ReportingPortalV3].[default]] (http-/192.168.1.124:8080-2) JBWEB000236: Servlet.service() for servlet default threw exception: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.rep.users.KZ_Users.roleList, no session or session was closed
public class CurrentUser extends User implements UserDetails {
private final Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
public CurrentUser(User user) {
super(user);
initAuthorities(user);
}
private void initAuthorities(User user) {
if (user.getRoles() == null) {
return;
}
for (Authority role : user.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getAuthority()));
}
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return authorities;
}
// implement the rest of UserDetails interface accordingly
}
public class UserDetailsServiceImpl extends UserDetailsService {
@Override
@Transactional(propagation = SUPPORTS, readOnly = true)
public CurrentUser loadUserByUsername(String username)
throws AuthenticationException ,DataAccessException {
ensureNotEmpty(username);
User user = userRepository.findUserWithAuthorities(username);
if (user == null) {
throw new UsernameNotFoundException("Invalid credentials!");
}
return new CurrentUser(user);
}
}