文章目录
接下来我们看看具体会出什么问题
一.整个Employee加载不出来了,报nosession错误
并且在/employee/page发送请求时报了500错误:
注意这个nosession错误,为什么会报这个错误
session是一级缓存,当em调用persist或者merge等方法时(此时还没有commit),session向数据库发送select语句进行查询,会将查询结果返回给session(以后当一级缓存有值就不用再查数据库了),session将结果分成拉两份,一份存在缓存,另一份就为快照。
当我执行em.close的时候就会去清空session,然后就会报nosession的错误了
这个问题应该从根源解决,即从持久化对象在哪里创建开始
1.持久化状态对象
如下代码,当我们调用findOne时,spring aop会为我们织入一些代码来开始事务和关闭session
如果不走这个,那employee就是new出来的,没有缓存这一说,因此我们发现新添加一条数据是可以成功的,只是当需要分页时会去查找employee这个对象,但是已经随着session被清除而没了
2.加过滤器
OpenEntityManagerInViewFilter将一个session与一次完整的请求过程对应的线程相绑定,这个过程会一直到view层的jsp代码被访问,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>
二.原来的错误解决了,报nosession错误
1.方式一,添加@JsonIgnoreProperties注解
被@JsonIgnoreProperties注解标注的字段或属性,返回的数据即不包含注解指定的一些属性
@ManyToOne(fetch = FetchType.LAZY)
/* jpa为了做懒加载,其中的一些属性无法被序列化 */
/* employee独享最终会转换成json格式发送给前台 */
/* 我们将这些属性用这个注解将其排除在这个过程中 */
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
@JoinColumn(name = "department_id")
/* 经过jpa之后department已经成为一个代理对象 */
private Department department;
2.方式二,重写com.fasterxml.jackson.databind.ObjectMapper
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 配置 -->
<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="cn.itsource.pss.common.CustomMapper"></bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
三.nosession解决了,然后又报错了
修改持久化对象的id就会报这个错