This is the first ever time i have had a problem i could not find the answer to, so here goes.
I am trying to serialize some model objects to JSON (using flexJSON), but am getting the following error:
Code:
java.lang.IllegalStateException: Cannot call isReadOnlyBeforeAttachedToSession when isReadOnlySettingAvailable == true
org.hibernate.proxy.AbstractLazyInitializer.isReadOnlyBeforeAttachedToSession(AbstractLazyInitializer.java:277)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:616)
flexjson.BeanProperty.getValue(BeanProperty.java:102)
flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:37)
flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:49)
flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:49)
flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:49)
flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
flexjson.JSONContext.transform(JSONContext.java:73)
flexjson.transformer.IterableTransformer.transform(IterableTransformer.java:29)
flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
flexjson.JSONContext.transform(JSONContext.java:73)
flexjson.JSONSerializer.serialize(JSONSerializer.java:377)
flexjson.JSONSerializer.serialize(JSONSerializer.java:235)
org.xxxxx.controller.admin.RecycleBinController.getDeletedDocsJson(RecycleBinController.java:69)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:616)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:212)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
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:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.xxxxx.filter.PagePreviewFilter.doFilter(PagePreviewFilter.java:62)
net.sf.ehcache.constructs.web.filter.GzipFilter.doFilter(GzipFilter.java:95)
net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.salvationarmy.commons.filters.HttpHeadFilter.doFilter(HttpHeadFilter.java:47)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
The problem seems to be one particular property within the model that is defined as follows:
Code:
@FullTextFilterDefs({ @FullTextFilterDef(name = "site", impl = SiteFilterFactory.class),
@FullTextFilterDef(name = "published", impl = PublishedFilterFactory.class) })
@Entity(name = "document")
@DiscriminatorColumn(name = "DTYPE", discriminatorType = DiscriminatorType.STRING)
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
public abstract class Document<T extends Document<?>> extends ModelObject implements Serializable, Comparable<T>,
Versionable {
/* many properties here. All of them work fine */
}
Code:
@Indexed(index = "content")
@Entity(name = "webpage")
@DiscriminatorValue("webpage")
@Audited
@Cacheable(true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "modelObjectCache")
public class WebPage extends Document<WebPage> {
private static final long serialVersionUID = 7045089818690794735L;
@NotNull
@ForeignKey(name = "TO_STRUCTURE_FK", inverseName = "TO_DOCUMENT_FK")
@OneToOne(mappedBy = "document", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@Fetch(FetchMode.JOIN)
@NotAudited
private Structure structure;
/* getters and setters here */
}
Code:
@Entity(name = "structure")
@Cacheable(true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "modelObjectCache")
public class Structure extends ModelObject implements Serializable, Comparable<Structure> {
/* The problem is with this property. If the getter for this property has @JSON(include=false) then the serialization works fine. */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fkParent")
@ForeignKey(name = "TO_PARENT_FK", inverseName = "TO_STRUCTURE_FK")
private WebPage parent;
@NotNull
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fkDocument")
@ForeignKey(name = "TO_DOCUMENT_FK", inverseName = "TO_STRUCTURE_FK")
@ContainedIn
private WebPage document;
/* getters and setters here. */
}
If it is useful, the relevant method in the controller goes as follows:
Code:
@SuppressWarnings("rawtypes")
@RequestMapping(value = "recycle_bin/json", method = RequestMethod.GET)
public @ResponseBody
String getDeletedDocsJson(@PathVariable("siteUrlAlias") String urlAlias, HttpServletResponse response) {
Site site = siteService.getSite(urlAlias);
List<Document> deletedDocs = docService.getDeletedDocs(site);
/* I have confirmed that deletedDocs is successfully populated */
JSONSerializer serializer = new JSONSerializer();
serializer.exclude("*.class");
serializer.exclude("*.content");
serializer.transform(new MapTransformer(), Map.class);
serializer.transform(new DateTransformer("yyyy-MM-dd'T'HH:mm:ssZ"), Date.class);
response.setContentType("application/json");
return serializer.serialize(deletedDocs);
}
This code used to work fine before we upgraded to Hibernate 4, and we are simply perplexed as to why this is happening now. Google searches have not given any clues as to any possible solutions.
I am using Hibernate Core 4.1 and flexjson 2.1. Let me know if any further information is required (or if i'm just being plain stupid).
Any suggestions are appreciated and thanks for reading,
rich.