What does Hibernate #Proxy(lazy = false) annotation do? - java

I was facing two different stack traces (see below) when trying to serialize my ESRBRating object which is a JPA entity. I am using Spring Data JPA. The controller called the service, service called the repository. I was able to resolve the issue by adding #Proxy(lazy = false) on my ESRBRating object.
My main question is what does #Proxy(lazy = false) actually do? Why does it work when adding it? Is this a good solution or will it have side effects such as performance / memory concerns?
For reference, this is my ESRBRating class now.
#Entity
#Table(name = "esrb_rating", schema = "igdb")
#JsonIgnoreProperties(ignoreUnknown = true)
#Proxy(lazy = false)
public class ESRBRating implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#NotNull
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private Long id;
#NotNull
#Size(min = 1, max = 255)
#Column(name = "title", nullable = false, length = 255)
private String title;
#Size(max = 65535)
#Column(length = 65535)
private String description;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "esrbRating")
private List<Game> games;
public ESRBRating() {
}
public ESRBRating(Long id, String title, String description) {
this.id = id;
this.title = title;
this.description = description;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Game> getGames() {
return games;
}
public void setGames(List<Game> games) {
this.games = games;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ESRBRating that = (ESRBRating) o;
return Objects.equal(this.id, that.id) &&
Objects.equal(this.title, that.title) &&
Objects.equal(this.description, that.description);
}
#Override
public int hashCode() {
return Objects.hashCode(id, title, description);
}
#Override
public String toString() {
return Objects.toStringHelper(this)
.add("id", id)
.add("title", title)
.add("description", description)
.toString();
}
}
Stack Trace:
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at net.jkratz.igdb.model.ESRBRating_$$_jvst319_0.getId(ESRBRating_$$_jvst319_0.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:466)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639)
... 76 more
I was also getting this stack trace.
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: net.jkratz.igdb.model.ESRBRating_$$_jvstb5c_0["handler"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: net.jkratz.igdb.model.ESRBRating_$$_jvstb5c_0["handler"])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:238)
at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:158)
at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:138)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: net.jkratz.igdb.model.ESRBRating_$$_jvstb5c_0["handler"])
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:59)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:26)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:114)
at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:1887)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:231)
... 72 more
Reference to my original question and issue: JsonMappingException: could not initialize proxy - no Session

#Proxy(lazy=false) will disable the default lazy loading for a particular entity. This means you always get the initialized entity whenever this entity is being referenced from other entities.
Using this annotation is usually a "code smell". If I were you, I would remove it and simply load all entity associations using the JOIN FETCH directive.

Related

SpringMVC - Hibernate: java.base/[Ljava.lang.Object; cannot be cast to

Group.java
package com.keating.model;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
#Entity
#Table(name = "t_group")
#JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Group implements Serializable {
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid")
#Column(name = "uuid", unique = true)
private String uuid;
#Column(name = "name", nullable = false, unique = true)
private String name;
#Column(name = "description", nullable = false, unique = false)
private String description;
#ManyToOne
#JoinColumn(name = "creatorUUID", nullable = false, unique = false)
private User creator;
#Column(name = "create_time", nullable = false)
private Date time = new Date();
public Group() {
}
public Group(String name, String description) {
this.name = name;
this.description = description;
}
public Group(String name, String description, User creator) {
this.name = name;
this.description = description;
this.creator = creator;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public User getCreator() {
return creator;
}
public void setCreator(User creator) {
this.creator = creator;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}
And there is my method.
public Group getInfo(String groupUUID) {
String hql = "SELECT group.uuid, group.name, group.description, group.time FROM Group group WHERE group.uuid=?";
Query query = this.getCurrentSession().createQuery(hql);
query.setParameter(0, groupUUID);
return (Group) query.uniqueResult();
}
And I think it is ok, but there are some exceptions:
HTTP Status 500 – Internal Server Errorh1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}HTTP Status 500 – Internal Server ErrorType Exception ReportMessage Request processing failed; nested exception is java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to com.keating.model.GroupDescription The server encountered an unexpected condition that prevented it from fulfilling the request.Exceptionorg.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to com.keating.model.Group
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Root Causejava.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to com.keating.model.Group
com.keating.dao.impl.GroupDaoImpl.getInfo(GroupDaoImpl.java:26)
com.keating.service.impl.GroupServiceImpl.getInfo(GroupServiceImpl.java:23)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:564)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
com.sun.proxy.$Proxy37.getInfo(Unknown Source)
com.keating.controller.GroupController.getInfo(GroupController.java:56)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:564)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Note The full stack trace of the root cause is available in the server logs.Apache Tomcat/9.0.2
Drop the list of fields you're trying to lookup
String hql = "FROM Group group WHERE group.uuid=?";

Spring Boot: Configuring AuthenticationManager with custom UserDetailsService

In my Spring Boot application, I am using JWT and a custom UserDetailsService. My AuthenticationManager is configured in a class annotated with #Configuration using the following method:
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
auth
.userDetailsService(userDetailsService)
.and()
.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder());
}
Even though I specified a UserDetailsService, I am faced with the following problem: When my JWTLoginFilter intercepts the login request, and getAuthenticationManager().authenticate(token)
is called, I get the following exception:
org.springframework.security.authentication.InternalAuthenticationServiceException: PreparedStatementCallback; bad SQL grammar [select username,password,enabled from users where username = ?]; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'butler-test.users' doesn't exist
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:126)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
at org.kehrbusch.butler.apigate.jwt.JWTLoginFilter.attemptAuthentication(JWTLoginFilter.java:35)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select username,password,enabled from users where username = ?]; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'butler-test.users' doesn't exist
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:684)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:716)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:726)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:776)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.loadUsersByUsername(JdbcDaoImpl.java:217)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.loadUserByUsername(JdbcDaoImpl.java:174)
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:114)
... 53 common frames omitted
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'butler-test.users' doesn't exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:942)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3966)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3902)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2526)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2673)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1962)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:692)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
... 60 common frames omitted
Setting a query using usersByUsernameQuery(query) on my AuthenticationManagerBuilder solves this problem, but is this the only solution? Shouldn't the UserDetailsService provide the information needed to retrieve the UserDetails for a username?
In case it helps, here is a snippet from the JWTLoginFilter:
#Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
AccountCredentials credentials = new ObjectMapper().readValue(httpServletRequest.getInputStream(), AccountCredentials.class);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
return getAuthenticationManager().authenticate(token);
}
This is my user entity (there are subclasses for specific users):
#Entity
#Table(name = "u_userdetails")
#Inheritance(strategy = InheritanceType.JOINED)
public class BasicUser implements UserDetails {
/**
*
*/
private static final long serialVersionUID = -109962402457721028L;
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "uuid2")
#Column(name = "id", columnDefinition = "BINARY(16)")
private UUID id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
public boolean isLocked() {
return locked;
}
#JsonDeserialize(using=LocalDateDeserializer.class)
#JsonSerialize(using=LocalDateSerializer.class)
#Column(name = "registration_date")
private LocalDate registrationDate;
#Column(name = "locked")
private boolean locked;
#Column(name = "enabled")
private boolean enabled;
#Column(name = "activation_key")
private String activationKey;
#Column(name = "email")
private String email;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "u_user_group",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "group_id", referencedColumnName = "id")
)
private List<Group> groups;
#ElementCollection
#CollectionTable(name="u_user_role", joinColumns=#JoinColumn(name="id"))
#Column(name="role")
private List<String> roles;
protected BasicUser() {}
public BasicUser(
#JsonProperty("id") UUID id,
#JsonProperty("username") String username,
#JsonProperty("password") String password,
#JsonProperty("registrationDate") LocalDate registrationDate,
#JsonProperty("locked") boolean locked,
#JsonProperty("enabled") boolean enabled,
#JsonProperty("activationKey") String activationKey,
#JsonProperty("email") String email,
#JsonProperty("roles") List<String> roles) {
this.id = id;
this.username = username;
this.password = password;
this.registrationDate = registrationDate;
this.locked = locked;
this.enabled = enabled;
this.activationKey = activationKey;
this.email = email;
this.roles = roles;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public static List<GrantedAuthority> getAuthorities(List<String> roles) {
List<GrantedAuthority> res = new ArrayList<>();
for(String role : roles) {
res.add(new BasicGrantedAuthority(role));
}
return res;
}
#Override
public String getPassword() {
return password;
}
#Override
public String getUsername() {
return username;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return !locked;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return enabled;
}
public LocalDate getRegistrationDate() {
return registrationDate;
}
public UUID getId() {
return id;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getAuthorities(roles);
}
public void setLocked(boolean locked) {
this.locked = locked;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getActivationKey() {
return activationKey;
}
public void setActivationKey(String activationKey) {
this.activationKey = activationKey;
}
}
Your configuration is wrong. You defined 2 authentication mechanisms, one is a user details service, and the second is a JDBC authentication.
In order to authenticate a user you only need one kind of mechanism to do that.
Your JVM "complains" about a bad SQL grammar, and if you'll examine the exception more closely you'll see that in particular JVM "complains" that he can't find the users table in your DB.
It seems that your JDBC authentication kicks in and tries to find the user credentials in the users DB table.
When you use this kind of authentication (JDBC) that is where and how Spring will try to authenticate the users, by trying to find a matching record within the users table in your DB.
You obviously mixing 2 authentications mechanisms by trying to read from:
#Table(name = "u_userdetails")
If you want to use JDBC authentication make sure to read the credentials from users table.
And not from:
#Table(name = "u_userdetails")

a hibernate LazyInitializationException which is very trick

I have two piece of code segments, they are almost exactly the same, except their locations are different, one locates in RestLoginDLCtrl(a controller) the other locates in CouponManagerController(a controller).But one code segment is right, the other one throws org.hibernate.LazyInitializationException.
I know how to solve my problem. confused me the most is why one is OK the other is wrong, but they are almost the same code. why? Any help would be appreciate.
ConversionCode is a value object which has a set named codeRewards and managerService is a service class.
note:
Finally, I found some interesting phenomena. when I use ajax way to post the http request, two methods both well:
$.ajax({
type: "POST",
url: "/CouponInfo/useConversionCode.do",
data: {
code: key
},
dataType: "json",
success: function (data) {
}
});
But when I use form way, two methods both did not work:Does hibernate lazy initialize mechnism has relationship with http request way?
<form action=""></form>
The CouponManagerController controller class:
#Controller
#RequestMapping(value = "${adminPath}/CouponInfo")
public class CouponManagerController extends RestBaseCtrl {
#Autowired
CouponManagerService managerService;
#ResponseBody
public void useConversionCode(String code, HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/json;charset=utf-8");
try {
LoginCustInfo info = (LoginCustInfo) request.getSession().getAttribute(SystemProperties.DUOLIJR_LOGIN_USER);
ConversionCode conversionCode = managerService.queryConversionCodeByCode(code);
if (conversionCode != null) {
managerService.useConversionCode(conversionCode, info.getCustId());
response.getWriter().print("[{\"success\":\"true\",\"message\":\"兑换成功\"}]");
} else {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"无效兑换码\"}]");
}
} catch (ParseException e) {
e.printStackTrace();
try {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"兑换失败!请稍后重试!\"}]");
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
try {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"兑换失败!请稍后重试!\"}]");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
The RestLoginDLCtrl controller class:
#Controller
#RequestMapping(value = "${adminPath}/yqxqrest/loginDLCtrl", method = RequestMethod.POST)
public class RestLoginDLCtrl extends RestBaseCtrl {
#Autowired
CouponManagerService managerService;
#RequestMapping(value = "useConversionCode")
#ResponseBody
public void useConversionCode(String code, HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/json;charset=utf-8");
try {
LoginCustInfo info = (LoginCustInfo) request.getSession().getAttribute(SystemProperties.DUOLIJR_LOGIN_USER);
ConversionCode conversionCode = managerService.queryConversionCodeByCode(code);
if (conversionCode != null) {
managerService.useConversionCode(conversionCode, info.getCustId());
response.getWriter().print("[{\"success\":\"true\",\"message\":\"兑换成功\"}]");
} else {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"无效兑换码\"}]");
}
} catch (ParseException e) {
e.printStackTrace();
try {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"兑换失败!请稍后重试!\"}]");
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
try {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"兑换失败!请稍后重试!\"}]");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
The CouponManagerServiceImpl service class:
#Service("ActivitiesCouponsService")
public class CouponManagerServiceImpl extends BaseServiceImpl implements CouponManagerService {
#Autowired
JdbcDao jdbcDao;
#Autowired
ActivitiesCouponsService couponsService;
#Override
public ConversionCode queryConversionCodeByCode(String code){
ConversionCode conversionCode=null;
String hql = " from ConversionCode where DELETE_FLAG=0 and state=0 and code='"+code+"'";
List<ConversionCode> codes = jdbcDao.find(hql);
if (codes.size()>0) {
conversionCode=codes.get(0);
}
return conversionCode;
}
/**
* 使用兑换码
* #param conversionCode
* #param custId
* #throws ParseException
*/
#Override
public void useConversionCode(ConversionCode conversionCode,Integer custId) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date now = new Date();
Calendar endTime = Calendar.getInstance();
endTime.setTime(sdf.parse(sdf.format(now)));
Set<ConversionCodeReward> codeRewards=conversionCode.getCodeRewards();
StringBuffer sb=new StringBuffer();
String a="";
for(ConversionCodeReward codeReward:codeRewards) {
CustActivitiesInfo activitiesInfo = new CustActivitiesInfo();
activitiesInfo.setCustId(custId);
activitiesInfo.setCouponsType(codeReward.getCouponsType());
String couponsName=couponsService.findUcTypeDictionaryBycode("COUPONS_TYPE", codeReward.getCouponsType() + "").getItemName();
activitiesInfo.setCouponsName(couponsName);
activitiesInfo.setActivitiesAmount(codeReward.getActivitiesAmount());
endTime.add(Calendar.DAY_OF_YEAR, Integer.valueOf(codeReward.getValidPeriod()));
endTime.add(Calendar.SECOND, -1);
activitiesInfo.setStartDate(sdf.parse(sdf.format(now)));
activitiesInfo.setEndDate(endTime.getTime());
activitiesInfo.setTaskAction("兑换码");
activitiesInfo.setUseMeetAmount(codeReward.getUseMeetAmount());
activitiesInfo.setUsePlanType(codeReward.getUsePlanType());
activitiesInfo.setUsePlanPeriod(codeReward.getUsePlanPeriod());
activitiesInfo.setState(1);
jdbcDao.saveObject(activitiesInfo);
sb.append("1张"+codeReward.getCouponsName()+"、");
}
conversionCode.setState(1);
jdbcDao.updateObject(conversionCode);
}
}
The ConversionCode value object class:
#Entity
#Table(name = "conversion_code")
public class ConversionCode extends BaseEntity implements java.io.Serializable{
private int id;
private String code;
private Date endDate;
private int state;
private String remark;
private Set<ConversionCodeReward> codeRewards;
public ConversionCode(int id,String code,Date endDate,int state,String remark){
super();
this.id=id;
this.code=code;
this.endDate=endDate;
this.state=state;
this.remark=remark;
}
public ConversionCode(){
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "code")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name = "end_date")
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
#Column(name = "state")
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
#ManyToMany(fetch=FetchType.LAZY,mappedBy="codes")
public Set<ConversionCodeReward> getCodeRewards() {
return codeRewards;
}
public void setCodeRewards(Set<ConversionCodeReward> codeRewards) {
this.codeRewards = codeRewards;
}
#Column(name = "remark")
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
The ConversionCodeReward value object class:
#Entity
#Table(name = "conversion_code_reward")
public class ConversionCodeReward extends BaseEntity implements java.io.Serializable{
private Integer id;
private String couponsName;
private int couponsType;
private double activitiesAmount;
private int validPeriod;
private double useMeetAmount;
private String usePlanType;
private int usePlanPeriod;
private Set<ConversionCode> codes;
public ConversionCodeReward(Integer id,String couponsName,int couponsType,double activitiesAmount,
int validPeriod,double useMeetAmount,String usePlanType,int usePlanPeriod){
super();
this.id=id;
this.couponsName=couponsName;
this.couponsType=couponsType;
this.activitiesAmount=activitiesAmount;
this.validPeriod=validPeriod;
this.useMeetAmount=useMeetAmount;
this.usePlanType=usePlanType;
this.usePlanPeriod=usePlanPeriod;
}
public ConversionCodeReward(){
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "coupons_name")
public String getCouponsName() {
return couponsName;
}
public void setCouponsName(String couponsName) {
this.couponsName = couponsName;
}
#Column(name = "coupons_type")
public int getCouponsType() {
return couponsType;
}
public void setCouponsType(int couponsType) {
this.couponsType = couponsType;
}
#Column(name = "activities_amount")
public double getActivitiesAmount() {
return activitiesAmount;
}
public void setActivitiesAmount(double activitiesAmount) {
this.activitiesAmount = activitiesAmount;
}
#Column(name = "valid_period")
public int getValidPeriod() {
return validPeriod;
}
public void setValidPeriod(int validPeriod) {
this.validPeriod = validPeriod;
}
#Column(name = "use_meet_amount")
public double getUseMeetAmount() {
return useMeetAmount;
}
public void setUseMeetAmount(double useMeetAmount) {
this.useMeetAmount = useMeetAmount;
}
#Column(name = "use_planType")
public String getUsePlanType() {
return usePlanType;
}
public void setUsePlanType(String usePlanType) {
this.usePlanType = usePlanType;
}
#Column(name = "use_planPeriod")
public int getUsePlanPeriod() {
return usePlanPeriod;
}
public void setUsePlanPeriod(int usePlanPeriod) {
this.usePlanPeriod = usePlanPeriod;
}
#ManyToMany(cascade={CascadeType.MERGE,CascadeType.REFRESH},fetch=FetchType.LAZY)
#JoinTable(name = "code_and_reward",
joinColumns = { #JoinColumn(name = "reward_id") },
inverseJoinColumns = { #JoinColumn(name = "code_id") })
#Where(clause="DELETE_FLAG=0")
public Set<ConversionCode> getCodes() {
return codes;
}
public void setCodes(Set<ConversionCode> codes) {
this.codes = codes;
}
}
The stack trace of the exception:
2015-12-16 15:38:34,059 ERROR (org.hibernate.LazyInitializationException:19) - failed to lazily initialize a collection of role: com.yiqixiangqian.entity.ConversionCode.codeRewards, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.yiqixiangqian.entity.ConversionCode.codeRewards, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
at com.yqxqfront.coupon.service.impl.CouponManagerServiceImpl.useConversionCode(CouponManagerServiceImpl.java:152)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
at com.yiqixiangqian.common.log.LogAspect.around(LogAspect.java:31)
at sun.reflect.GeneratedMethodAccessor255.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy119.useConversionCode(Unknown Source)
at com.yqxqfront.rest.controller.RestLoginDLCtrl.useConversionCode(RestLoginDLCtrl.java:665)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:144)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.yqxqfront.rest.filter.SessionFilter.doFilter(SessionFilter.java:186)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.yqxqfront.filter.ImageVerifyCodeFilter.doFilter(ImageVerifyCodeFilter.java:66)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:615)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:879)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:617)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1774)
at java.lang.Thread.run(Thread.java:662)
Hibernate: select custmessag0_.UID as UID245_, custmessag0_.CREATE_DATE as CREATE2_245_, custmessag0_.CREATED_BY as CREATED3_245_, custmessag0_.DELETE_FLAG as DELETE4_245_, custmessag0_.LAST_UPDATE_DATE as LAST5_245_, custmessag0_.UPDATE_BY as UPDATE6_245_, custmessag0_.VERSION as VERSION245_, custmessag0_.CONTENT as CONTENT245_, custmessag0_.CUST_ID as CUST9_245_, custmessag0_.ISCHECK as ISCHECK245_, custmessag0_.PUB_DATE as PUB11_245_, custmessag0_.TITLE as TITLE245_, custmessag0_.TYPE as TYPE245_ from cust_message custmessag0_ where custmessag0_.CUST_ID=? and custmessag0_.ISCHECK=? and custmessag0_.DELETE_FLAG=0
failed to lazily initialize a collection of role: com.yiqixiangqian.entity.ConversionCode.codeRewards, no session or session was closed
The useConversionCode() method which locates in CouponManagerController controller is OK:
The useConversionCode() method which locates in RestLoginDLCtrl controller is wrong and throws a LazyInitializationException exception:
Finally, I found some interesting phenomena. when I use ajax way to post the http request, two methods both well:
$.ajax({
type: "POST",
url: "/CouponInfo/useConversionCode.do",
data: {
code: key
},
dataType: "json",
success: function (data) {
}
});
but when I use form way, two methods both did not work:
<form action=""></form>
Does hibernate lazy initialize mechnism has relationship with http request way?
I know how this issue occured.Suddenly, I found there is a OpenSessionInViewFilter in the web.xml file.
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
In my form post request way, I did not add the .do request suffix, so the OpenSessionInViewFilter did not work, so the LazyInitializationException occured.
But the ajax post request way added the .do request suffix, so the OpenSessionInViewFilter worked and LazyInitializationException did not occur.

How to display a List with Spring <form:input>

I'm trying to show a list of object 'Persona' using <form:input>.
This is my form
<form:form modelAttribute="persona">
<c:forEach items="${personaList}" varStatus="contatore" var="persona">
<form:input path="persona[${contatore.index}].id"/><br/>
...
</c:forEach>
</form:form>
This is the error I get:
org.springframework.beans.NotReadablePropertyException: Invalid property 'persona[0]' of bean class [com.springgestioneerrori.model.Persona]: Bean property 'persona[0]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:729)
org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:576)
org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:553)
org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:719)
org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:219)
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:120)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:178)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:198)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:164)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:151)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:142)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:126)
org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:421)
org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
org.apache.jsp.WEB_002dINF.views.persona_jsp._jspx_meth_form_005finput_005f0(persona_jsp.java:249)
org.apache.jsp.WEB_002dINF.views.persona_jsp._jspx_meth_c_005fforEach_005f0(persona_jsp.java:169)
org.apache.jsp.WEB_002dINF.views.persona_jsp._jspx_meth_form_005fform_005f0(persona_jsp.java:124)
org.apache.jsp.WEB_002dINF.views.persona_jsp._jspService(persona_jsp.java:86)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:439)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:954)
org.apache.jasper.runtime.PageContextImpl.doInclude(PageContextImpl.java:688)
org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:682)
org.apache.tiles.jsp.context.JspTilesRequestContext.include(JspTilesRequestContext.java:103)
org.apache.tiles.jsp.context.JspTilesRequestContext.dispatch(JspTilesRequestContext.java:96)
org.apache.tiles.renderer.impl.UntypedAttributeRenderer.write(UntypedAttributeRenderer.java:61)
org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:103)
org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:669)
org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:337)
org.apache.tiles.jsp.taglib.InsertAttributeTag.render(InsertAttributeTag.java:234)
org.apache.tiles.jsp.taglib.InsertAttributeTag.render(InsertAttributeTag.java:211)
org.apache.tiles.jsp.taglib.RenderTag.doEndTag(RenderTag.java:220)
org.apache.jsp.WEB_002dINF.template.default_.template1_jsp._jspx_meth_tiles_005finsertAttribute_005f2(template1_jsp.java:284)
org.apache.jsp.WEB_002dINF.template.default_.template1_jsp._jspService(template1_jsp.java:115)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:439)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.apache.tiles.servlet.context.ServletTilesRequestContext.forward(ServletTilesRequestContext.java:241)
org.apache.tiles.servlet.context.ServletTilesRequestContext.dispatch(ServletTilesRequestContext.java:222)
org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:103)
org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:669)
org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:689)
org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:643)
org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:626)
org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:322)
org.springframework.web.servlet.view.tiles2.TilesView.renderMergedOutputModel(TilesView.java:124)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1180)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:950)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
This is Persona.class:
#Component
#MappedSuperclass
public class Persona implements Serializable{
private static final long serialVersionUID = -5313982287615353480L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id", nullable=false, updatable=false)
private int id;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "sesso")
private Sesso sesso;
#Column(name="data_di_nascita", nullable=false, updatable=true)
#DateTimeFormat(pattern="yyyy/MM/dd")
private Date dataDiNascita;
#Column(name="luogo_di_nascita", nullable=false, updatable=true)
#Size(min=2, max=45)
#Pattern(regexp="^[A-Za-z09]*$.-_,")
private String luogoDiNascita;
#Column(name="peso_in_kg", nullable=false, updatable=true)
#Pattern(regexp="[0-9]")
#Size(min=2,max=3)
private int pesoInKg;
#Column(name="altezza_in_cm", nullable=false, updatable=true)
#Pattern(regexp="[0-9]")
#Size(min=2,max=3)
private int altezzaInCm;
#Column(name="nome", nullable=false, updatable=true)
#Size(min=1,max=45)
#Pattern(regexp="^[A-Za-z09]*$.-_,")
private String nome;
#Column(name="cognome", nullable=false, updatable=true)
#Size(min=1,max=45)
#Pattern(regexp="^[A-Za-z09]*$.-_,")
private String cognome;
#Column(name="indirizzo", nullable=false, updatable=true)
#Size(min=3,max=45)
#Pattern(regexp="^[A-Za-z09]*$.-_,")
private String indirizzo;
public Persona() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Sesso getSesso() {
return sesso;
}
public void setSesso(Sesso sesso) {
this.sesso = sesso;
}
public Date getDataDiNascita() {
return dataDiNascita;
}
public void setDataDiNascita(Date dataDiNascita) {
this.dataDiNascita = dataDiNascita;
}
public String getLuogoDiNascita() {
return luogoDiNascita;
}
public void setLuogoDiNascita(String luogoDiNascita) {
this.luogoDiNascita = luogoDiNascita;
}
public int getPesoInKg() {
return pesoInKg;
}
public void setPesoInKg(int pesoInKg) {
this.pesoInKg = pesoInKg;
}
public int getAltezzaInCm() {
return altezzaInCm;
}
public void setAltezzaInCm(int altezzaInCm) {
this.altezzaInCm = altezzaInCm;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
public String getIndirizzo() {
return indirizzo;
}
public void setIndirizzo(String indirizzo) {
this.indirizzo = indirizzo;
}
}
Thank you
Use ${persona.id} instead of persona[${contatore.index}].id
This line:
<c:forEach items="${personaList}" varStatus="contatore" var="persona">
means "repeat the content for each item in personaList, while tracking the iteration status in contatore and assigning the current item into persona". So the framework has already done the assignment persona = personaList[contatore.id] for you.
Also, the whole expression to be evaluated needs to be inside the ${...} markup.
Use this :
<form:form modelAttribute="persona">
<c:forEach items="${personaList}" varStatus="count" var="person">
<input type="text" name="persona.persona[${count.index}].id" value="${person.id}"/><br/>
</c:forEach>
</form:form>

java jpa ManyToOne cascade remove not working as expected

I have two tables and on one of which I want to perform cascade on delete operation. I have tried using annotations both on the variable and on the getter method as well, but the variable one gives me this error:
An error occured
org.hibernate.exception.DataException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:102)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at no.nhst.user.dao.hibernate.IPUserDAOImpl.saveOrUpdate(IPUserDAOImpl.java:78)
at no.nhst.user.service.IPUserServiceImpl.saveOrUpdateIPUser(IPUserServiceImpl.java:103)
at no.nhst.user.web.admin.IPCustomerController.submitIpUsers(IPCustomerController.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.sql.BatchUpdateException: Data truncation: Out of range value adjusted for column 'user_account' at row 1
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2028)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1451)
at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 79 more
Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Out of range value adjusted for column 'user_account' at row 1
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3607)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2427)
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1980)
... 84 more
Which is out of question because the column its referring to has BIGINT(10) size.
And, when I try using many to one annotation on getter method its not doing anything at all.
Here is my parent entity class:
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import no.nhst.user.model.resolver.AuthoritiesResolver;
import no.nhst.user.model.resolver.DefaultAuthoritiesResolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
#Entity
#Table(name = "ac_useraccount", uniqueConstraints = { #UniqueConstraint(columnNames = { "domain", "username" }) })
public class UserAccount extends BaseEntity implements UserDetails {
private static final long serialVersionUID = 1L;
private static final Log logger = LogFactory.getLog(UserAccount.class);
private String domain;
private String username;
private String password;
private String email;
private UserProfile userProfile;
private Date created;
private Date lastlogin;
private Date expires;
private Date credentialsExpires;
private boolean enabled = false;
private boolean locked = false;
private Set<Role> roles;
private Set<Group> groups;
private Set<UserApplication> applications;
private Set<Tag> tags = new HashSet<Tag>(); // optional "tags" to categorize a user in some way (not required)
private int maxSessions;
private AuthoritiesResolver authoritiesResolver;
UserAccount() {
this.applications = new HashSet<UserApplication>();
this.authoritiesResolver = new DefaultAuthoritiesResolver();
}
UserAccount(String domain, String username) {
this(domain, username, null, null, false);
}
UserAccount(String domain, String username, String password, String email, boolean enabled) {
this();
this.domain = domain;
this.username = username;
this.password = password;
this.email = email;
this.enabled = enabled;
}
public void setDomain(String domain) {
this.domain = domain;
}
public void setUserProfile(UserProfile userProfile) {
this.userProfile = userProfile;
if (null != userProfile)
userProfile.setUserAccount(this);
}
/** See http://docs.jboss.org/hibernate/core/3.5/reference/en-US/html/objectstate.html#objectstate-transitive */
// TODO: See AVIS-589 (update: that Jira issue is resolved)
#OneToOne(orphanRemoval=false,fetch = FetchType.LAZY)
#Cascade({CascadeType.ALL})
public UserProfile getUserProfile() {
return userProfile;
}
// TODO: AVIS-607, set to FetchType.EAGER temporarily
#OneToMany(mappedBy="userAccount", fetch=FetchType.LAZY)
#Cascade({CascadeType.ALL})
public Set<UserApplication> getApplications() {
return this.applications;
}
public void setApplications(Set<UserApplication> applications) {
this.applications = applications;
}
#OneToMany(mappedBy = "userAccount")
#Cascade({CascadeType.ALL})
public Set<Tag> getTags() {
return tags;
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
#Basic
public int getMaxSessions() {
return maxSessions;
}
public void setMaxSessions(int maxSessions) {
this.maxSessions = maxSessions;
}
#Temporal(TemporalType.TIMESTAMP)
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
#Temporal(TemporalType.TIMESTAMP)
public Date getLastlogin() {
return lastlogin;
}
public void setLastlogin(Date lastlogin) {
this.lastlogin = lastlogin;
}
// Transient (dependent on other fields) Spring Security UserDetails methods
#Transient
public Set<GrantedAuthority> getAuthorities() {
return authoritiesResolver.resolveAuthorities(this);
}
#Transient
public boolean isAccountNonExpired() {
boolean accountNonExpired = true;
if(this.expires != null) {
Date now = new Date();
if(now.after(expires)) {
accountNonExpired = false;
}
}
return accountNonExpired;
}
#Transient
public boolean isCredentialsNonExpired() {
boolean credentialsNonExpired = true;
if(this.credentialsExpires != null) {
Date now = new Date();
if(now.after(credentialsExpires)) {
credentialsNonExpired = false;
}
}
return credentialsNonExpired;
}
#Transient
public boolean isAccountNonLocked() {
return !this.locked;
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.locked = !accountNonLocked;
}
public void setAuthoritiesResolver(AuthoritiesResolver authoritiesResolver) {
this.authoritiesResolver = authoritiesResolver;
}
#Transient
public AuthoritiesResolver getAuthoritiesResolver() {
return authoritiesResolver;
}
#Transient
public void addRole(Role role) {
this.getRoles().add(role);
role.getUserAccounts().add(this);
}
#Transient
public void removeRole(Role role) {
this.getRoles().remove(role);
role.getUserAccounts().remove(this);
}
#Transient
public void addGroup(Group group) {
this.getGroups().add(group);
group.getUserAccounts().add(this);
}
}
And here is my child class where I have used many to one annotation:
import org.hibernate.annotations.*;
import javax.persistence.*;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Table;
#Entity
#Table(name="ac_ua_ip")
public class IPUser extends BaseEntity{
private static final long serialVersionUID = 1L;
private String ip;
private String comment;
private UserAccount userAccount;
public IPUser(){
}
public IPUser (String ip, String comment, UserAccount userAccount){
this.ip = ip;
this.comment = comment;
this.setUserAccount(userAccount);
}
#Column (nullable = false)
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
#Column
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
#ManyToOne(cascade = CascadeType.REMOVE)
public UserAccount getUserAccount() {
return userAccount;
}
public void setUserAccount(UserAccount userAccount) {
this.userAccount = userAccount;
}
}
And, I have removed lot of methods from parent class here just to have a clarity.
Any suggestions as to what I am doing wrong?
You will have to manage that problem manually, as it really does NOT make sense to cascade the remove operations from a ManyToOne relationship (otherwise your DB will not be consistent, as there could remain some IPUser entities without UserAccount).
See this answer for an excerpt from the JPA specification + a similar problem.
Alright, here's how I made it work.
I hope it goes all ok with the etiquette of answering self-asked-questions.
I added a reference to IPUser class in UserAccount class and it worked smoothly now. Here is the snippet I added:
private List<IPUser> ipUserList;
#OneToMany(mappedBy = "userAccount", fetch = FetchType.LAZY)
#Cascade({CascadeType.DELETE})
public List<IPUser> getIpUserList() {
return ipUserList;
}
public void setIpUserList(List<IPUser> ipUserList) {
this.ipUserList = ipUserList;
}
Please feel free to update my answer or ask any question regarding this.

Categories

Resources