我正在尝试将实体转换为Rest服务中使用的DTO。
我的实体如下:
@Entity
@Table(name = "USERS")
public class User extends AbstractEntity {
@Column(name = "LOGIN")
private String login;
@Column(name = "PASSWORD")
private String password;
@Column(name = "ENABLED")
private Boolean enabled;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "EMAIL")
private String email;
@Column(name = "DATE_FORMAT")
private String dateFormat;
@Column(name = "CREATION_DATE")
private LocalDateTime creationDate;
@Column(name = "LAST_ACCESS_DATE")
private LocalDateTime lastAccessDate;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "USER_ROLES", joinColumns = {
@JoinColumn(name = "USER_ID", referencedColumnName = "id") }, inverseJoinColumns = {
@JoinColumn(name = "ROLE_ID", referencedColumnName = "id") })
private List<Role> roles = new ArrayList<>();
以及相关的DTO:
public class UserDto extends AbstractDto {
private String login;
private String password;
private Boolean enabled;
private String firstName;
private String lastName;
private String email;
private String dateFormat;
private LocalDateTime creationDate;
private LocalDateTime lastAccessDate;
private List<RoleDto> roles = new ArrayList<>();
我正在使用ModelMapper以便将我的实体转换为DTO,反之亦然。但是,当我向Rest API发送请求时,出现以下错误:
Converter org.modelmapper.internal.converter.MergingCollectionConverter@67aa8104 failed to convert org.hibernate.collection.internal.PersistentBag to java.util.List.
1 error
at org.modelmapper.internal.Errors.throwMappingExceptionIfErrorsExist(Errors.java:380) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:81) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.ModelMapper.mapInternal(ModelMapper.java:573) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.ModelMapper.map(ModelMapper.java:406) ~[modelmapper-2.3.3.jar:na]
at eu.voiceweb.business.services.MapperService.getMappedObject(MapperService.java:49) ~[Reporting-3.2.0.jar:na]
at eu.voiceweb.business.services.MapperService.getDto(MapperService.java:31) ~[Reporting-3.2.0.jar:na]
at eu.voiceweb.business.services.UserService.getUserByLogin(UserService.java:63) ~[Reporting-3.2.0.jar:na]
at eu.voiceweb.restapi.UserController.getUserByUsername(UserController.java:45) ~[dialogManager-3.2.0.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) ~[spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) [servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [catalina.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.12]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-websocket.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.12]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [catalina.jar:9.0.12]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:9.0.12]
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45) [tomee-catalina-8.0.0-M2.jar:8.0.0-M2]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [catalina.jar:9.0.12]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [catalina.jar:9.0.12]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [catalina.jar:9.0.12]
at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97) [tomee-catalina-8.0.0-M2.jar:8.0.0-M2]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668) [catalina.jar:9.0.12]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [catalina.jar:9.0.12]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [catalina.jar:9.0.12]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-coyote.jar:9.0.12]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-coyote.jar:9.0.12]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770) [tomcat-coyote.jar:9.0.12]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-coyote.jar:9.0.12]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:9.0.12]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:9.0.12]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: eu.voiceweb.persistence.entities.User.roles, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:602) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:217) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:161) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:287) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.modelmapper.internal.util.Iterables.getLength(Iterables.java:50) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:44) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:31) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:115) ~[modelmapper-2.3.3.jar:na]
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:72) ~[modelmapper-2.3.3.jar:na]
... 47 common frames omitted
2019-05-15 13:25:26,065 ERROR [http-nio-18000-exec-9] [AbstractAuthenticationProcessingFilter.java:221] An internal error occurred while trying to authenticate the user.
org.springframework.security.authentication.InternalAuthenticationServiceException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:123) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:200) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) [spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) [spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.12]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [catalina.jar:9.0.12]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:9.0.12]
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45) [tomee-catalina-8.0.0-M2.jar:8.0.0-M2]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [catalina.jar:9.0.12]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [catalina.jar:9.0.12]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [catalina.jar:9.0.12]
at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97) [tomee-catalina-8.0.0-M2.jar:8.0.0-M2]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668) [catalina.jar:9.0.12]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [catalina.jar:9.0.12]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [catalina.jar:9.0.12]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-coyote.jar:9.0.12]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-coyote.jar:9.0.12]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770) [tomcat-coyote.jar:9.0.12]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-coyote.jar:9.0.12]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:9.0.12]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:9.0.12]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226) ~[gson-2.8.5.jar:na]
at com.google.gson.Gson.fromJson(Gson.java:927) ~[gson-2.8.5.jar:na]
at com.google.gson.Gson.fromJson(Gson.java:892) ~[gson-2.8.5.jar:na]
at com.google.gson.Gson.fromJson(Gson.java:841) ~[gson-2.8.5.jar:na]
at com.google.gson.Gson.fromJson(Gson.java:813) ~[gson-2.8.5.jar:na]
at eu.voiceweb.services.UserService.getUserFromResponse(UserService.java:104) ~[classes/:na]
at eu.voiceweb.services.UserService.getUserByUsername(UserService.java:78) ~[classes/:na]
at eu.voiceweb.services.UserService.loadUserByUsername(UserService.java:115) ~[classes/:na]
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:108) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
... 41 common frames omitted
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385) ~[gson-2.8.5.jar:na]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215) ~[gson-2.8.5.jar:na]
... 49 common frames omitted
最初,实体中的访存类型为LAZY,我将其更改为EAGER,并且可以工作。但是我读到这对项目的性能不利。我已经在Web应用程序的初始值设定项类中尝试了OpenSessionInViewFilter,但没有结果。是否有解决方法?
答案 0 :(得分:0)
错误是
由以下原因引起:org.hibernate.LazyInitializationException:懒惰 初始化角色集合: eu.voiceweb.persistence.entities.User.roles,无法初始化 代理-没有会话
因此,这意味着在序列化对象时不会初始化角色列表。
您必须确保在读取数据的地方进行初始化。
例如,在查询中使用JOIN FETCH,EntityGraph或仅在数据访问层中访问集合。