延迟加载问题:Hibernate 3、Spring 4、Jackson 2.4.0

Posted

技术标签:

【中文标题】延迟加载问题:Hibernate 3、Spring 4、Jackson 2.4.0【英文标题】:Lazy load Issue : Hibernate 3, Spring 4, Jackson 2.4.0 【发布时间】:2014-11-02 00:59:18 【问题描述】:

我的项目正在使用

Spring 4.0.5.RELEASE 休眠 3.6.0.FINAL jackson-datatype-hibernate3-2.4.0.jar

问题: /Spring4HibernateMaven/contacts/3 产生 LazyInitializationException!!

将 ObjectMapper(请参阅 spring-servlet.xml)更改为 com.company.gis.ucvs.ioe.json.HibernateAwareObjectMapper 以将 Contact POJO 转换为 JSON 失败并出现异常。但是,如果我只是创建一个虚拟联系人对象,POJO 到 JSON 的转换工作正常。我错过了什么?非常感谢您的帮助/指点..谢谢!

堆栈跟踪

org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话 org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167) org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215) org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190) com.company.gis.ucvs.ioe.form.Contact_$$_javassist_6.getId(Contact_$$_javassist_6.java) sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) com.fasterxml.jackson.databind.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:726) com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:506) com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644) com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152) com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:114) com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:1837) org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal(MappingJackson2HttpMessageConverter.java:253)

来自 spring-servlet.xml 的片段

<!-- Configure to plugin JSON as request and response in method handler -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jsonMessageConverter"/>
        </list>
    </property>
</bean>

<!-- Configure bean to convert JSON to POJO and vice versa -->
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
**<!--  bean id="jacksonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" /-->
<bean id="jacksonObjectMapper" class="com.company.gis.ucvs.ioe.json.HibernateAwareObjectMapper" />**

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonObjectMapper" />
<property name="targetMethod" value="configure" />
<property name="arguments">
    <list>
        <value type="com.fasterxml.jackson.databind.DeserializationFeature">FAIL_ON_UNKNOWN_PROPERTIES</value>
        <value>false</value>
    </list>
</property>
</bean>    

来自 ContactController.java 的片段

@RequestMapping(value = "/contacts/id", method = RequestMethod.GET,headers="Accept=application/json")
public @ResponseBody Contact getContact(@PathVariable Integer id)  

    //Contact c = new Contact(); <--- Sample contact POJO to JSON works fine
    //c.setEmail("NO EMAIL");
    Contact c = contactService.getContact(id);
    return c;


来自 ContactServiceImpl.java 的片段

@Transactional
public Contact getContact(Integer id) 
    Contact c = contactDAO.getContact(id);
    return c;


来自 ContactDaoImpl.java 的 SNIPPET

@Autowired
private SessionFactory sessionFactory;

public Contact getContact(Integer id) 
    Contact contact = (Contact) sessionFactory.getCurrentSession().load(
            Contact.class, id);
    return contact;

来自 HibernateAwareObjectMapper 的片段

@SuppressWarnings("serial")
public class HibernateAwareObjectMapper extends ObjectMapper 

    public HibernateAwareObjectMapper() 
        Hibernate3Module hm = new Hibernate3Module();
        registerModule(hm);  
        //Whether lazy-loaded object should be forced to be loaded and then serialized (true); or serialized as nulls (false).Default value is false. 
        hm.configure(Hibernate3Module.Feature.FORCE_LAZY_LOADING, true);
    

 

【问题讨论】:

描述您想要解决的确切问题以及到目前为止您尝试解决的问题。仔细阅读***.com/tour 这个问题与你的@Transactional有关。 Jackson 正在尝试加载您的 Contact 对象,该对象与其他对象具有一对多映射,并且您的获取类型是 Lazy。你应该在网上搜索这个问题。 SO 说只有当您在任何地方都没有得到答案时才发布问题。 【参考方案1】:

您正在处理分离的实体。一旦您的对象离开 @Transactional 方法,它们就会被分离。将这些转换为 DTO(数据传输对象)或取消代理您的对象,请参阅 http://java-success.blogspot.de/2012/09/understanding-hibernate-proxy-objects.html

【讨论】:

以上是关于延迟加载问题:Hibernate 3、Spring 4、Jackson 2.4.0的主要内容,如果未能解决你的问题,请参考以下文章

SSH项目web.xml文件的常用配置struts2的过滤器spring监听器解决Hibernate延迟加载问题的过滤器解决中文乱码的过滤器

延迟加载有效,但不应该

Spring boot JPA - 延迟加载不适用于一对一映射

Hibernate检索策略之延迟加载和立即加载

spring中怎么实现过滤器和监听器?

OpenSessionInViewFilter配置和作用