springDataJpa懒加载引发问题

springDataJpa懒加载问题

springDataJpa懒加载

现在我有一个员工的domain,员工里有一个部门,部门是另外的一个实体。为了推迟和数据库交互的时间,推迟到真正需要这个对象数据的时候,提高系统的性能,,现在部门我要使用懒加载。
延迟加载(lazy load) (也称为懒加载,也叫延迟实例化,延迟初始化等)主要表达的思想就是:把对象的创建延迟到使用的时候创建,而不是对象实例化的时候创建。延迟加载机制是为了避免一些无谓的性能开销而提出来的,这种方式避免了性能的浪费。所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。

@Entity
@Table(name = "employee")
public class Employee extends BaseDomain {
    private String username;

    private String password;

    private String email;

    private Integer age;

    private String headImage = "/images/head/1.jpg";

    //部门使用懒加载
    @ManyToOne(fetch = FetchType.LAZY)
    //部门对应employee表中的department_id字段
    @JoinColumn(name = "department_id")
    private Department department;
    //省略getter和setter,tostring

no session问题

如果我们只是这样做就会产生 一个no-session的问题,No Session found for current thread],那么这个问题是怎么产生的呢?
当使用hibernate框架操作数据库的时候,如果做查询的话会有立即加载(get)和延迟加载(load)的区别,延迟加载表示,当你查询某个数据(假设是对象)的时候,hibernate不会立马发送sql语句,而是当我们调用这个对象的属性的时候,也就是真正使用查询出来的数据的时候才会发送sql语句去一级缓存(即session,这里的session和域对象session没有半毛钱关系)中获取,但是正常这个session的开启核关闭是在service层执行的,但是我们真正使用查询的对象的数据时,是在web层,但是这个时候session已经关闭,就会报no-session异常。

解决办法

我们只需要在web.xml中配置一个filter。

<!--解决懒加载no session问题-->
  <filter>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

no Serializable

这时候就会产生另外一个问题,
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) ),
这是因为部门对象是一个代理对象,懒加载产生的对象都是代理对象,所以其中有些属性是不可序列化的,提供两种解决方案:

一劳永逸

新建一个类:

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * 自定义映射,解决Serializa的问题
 */
public class CustomMapper extends ObjectMapper {
    public CustomMapper() {
        this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 设置 SerializationFeature.FAIL_ON_EMPTY_BEANS 为 false
        this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }
}

再在spring-mvc.xml中配置;

 <!-- Spring MVC 配置 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json; charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded; charset=UTF-8</value>
                    </list>
                </property>
                <!-- No serializer:配置 objectMapper 为我们自定义扩展后的 CustomMapper,解决了返回对象有关系对象的报错问题 -->
                <property name="objectMapper">
                    <bean class="com.cl.easysell.common.CustomMapper"></bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

注解

这个错我们可以到网上搜索,SpringMVC与Jpa集成的时候(有懒加载)就会出现这个问题
(这是因为你需要序列化对象有一个属性是一类类型,而你使用了Hibernate的延迟加载所以这里是个Hibernate的代理对象。该代理对象有些属性不能被序列化所以会报错。)
在类上加属性:生成的时候把这个字段忽略了:
@JsonIgnoreProperties(value={“hibernateLazyInitializer”,“handler”,“fieldHandler”})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值