SpringJPA FAQ

Backend SpringJpa Frequently Asked Questions Summary

Common Errors ① no-session

Cause lazy loading caused (OpenEntityManagerInViewFilter arranged in web.xml) ==

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         id="WebApp_ID" version="3.1">

  <!--注意:SpringMVC的配置和Spring的配置要单独读取,否则后面集成其它框架会出问题-->

  <!--读取Spring的配置 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>


  <!--配置的核心控制器DispatcherServlet-->
  <servlet>
    <servlet-name>dispatchServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--读取SpringMvc配置-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext-mvc.xml</param-value>
    </init-param>
    <!--tomcat启动优先级-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatchServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!--编码过滤-->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!--配置过滤器(Spring为我们写好的:让我们EntityManager对象在页面展示完后再关闭解决noSesion问题(懒加载引起的))
  因为我们使用懒加载,
  查询员工后EntityManager对象就关闭了,所以当页面再去加载department部门数据时就会发生no-session问题,
  所以我们要延迟EntityManager对象关闭的时间
  -->
  <filter>
    <filter-name>openEntityManager</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>openEntityManager</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- shiro的过滤器(帮我们拦截请求)-》什么事情都不做
  Delegating:授(权); 把(工作、权力等)委托(给下级); 选派(某人做某事)
  Proxy:代理 -> 需要通过名称(shiroFilter)去找真正的过滤器
  -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
      <param-name>targetFilterLifecycle</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

Common Mistakes ② no-serializer

The reason serialization problems caused jpa lazy load the object itself as filling some of the properties, ( "hibernateLazyInitializer", "handler ", "fieldHandler"),
these properties will affect the SpringMVC return Json (because there is a return to introspection facilities,
because you need to serialize object has a property is a class type, and you use lazy loading Hibernate so here is a Hibernate proxy object the proxy object some properties can not be serialized it will report an error.
so ignore these attributes allowed not to participate Serialization

Solution one: Add comment (but with the increase in domain classes, the workload will increase)

Solution two: xml configuration once and for all

Rewrite: ObjectMapper, and then configure the mapping applicationContext-mvc.xml (this method once and for all, followed by lazy loading in the Spring JPA integration that they will avoid errors No serializer

Rewrite ObjectMapper relational mapping

package cn.itsource.aisell.common;

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

//重写了原生的映射关系
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);
    }
}

In the configuration applicationContext-mvc.xml

  <!--SpringMVC配置 解决No serializer问题-->
    <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.aisell.common.CustomMapper"></bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

Common Mistakes ③ n-to-n

Cause: The persistent object can not be modified Oid

Solution: Empty the related object data

Back-end code EmployeeController Code

/**
    * 在你路径访问所有方法前都会先执行这个方法
    * 还能接受前台数据
    * 作用为修改方法创建一个对象包含所有信息
    *  @ModelAttribute("updateEmployee") 注解后面参数可以定位到具体方法把这个返回的对象返回给SpringMVC
    *  的对象复制一份给mvc的对象
    * @param id
    * @param _cmd
    * @return
    */
   @ModelAttribute("updateEmployee")
   public  Employee beforeUpdate(Long id , String _cmd){
       if (Objects.nonNull(id)&&Objects.equals("update",_cmd)){
           //根据id查询到修改数据的信息放在临时对象中但这个对象是持久化状态所有不能修改关联部门表的id否则报n-to-n
           Employee tempEmployee = employeeService.findOne(id);
           //把关联对象设置为空,就可以解决n-to-n问题了  持久化对象不可以修改它的OID
           tempEmployee.setDepartment(null);
           return  tempEmployee;
       }
       return  null;
   } 
 /**
     * 修改的方法
     * @param employee
     * @return
     * @ModelAttribute("updateEmployee")Employee employee此时mvc创建的Employee对象
     * 就是@ModelAttribute("updateEmployee")方法返回的对象包含对应Employee的所有信息
     * 用过前台传输数据进行属性注入此时密码一些信息就不会丢失而且因为关联对象department
     * 也清空了所有属性所以不会出现n-to-n问题了
     */
    @ResponseBody
    @RequestMapping("/update")
    public  JsonResult update( @ModelAttribute("updateEmployee")Employee employee){
            return  saveOrUpdate(employee);
    }   

Guess you like

Origin www.cnblogs.com/qdmpky/p/11921589.html