摘要:究其原因就是沒有辦法被序列化,網(wǎng)上有很多的方法,例如,這是治標(biāo)不治本的方法現(xiàn)在要達(dá)到的目標(biāo)是當(dāng)有關(guān)聯(lián)數(shù)據(jù)的時(shí)候序列化,不存在的時(shí)候不返回,或者直接返回。到這里我們就可以達(dá)到預(yù)期的目的了。
Spring Jpa這項(xiàng)技術(shù)在Spring 開發(fā)中經(jīng)常用到。
今天在做項(xiàng)目用到了Entity的關(guān)聯(lián)懶加載,但是在返回Json的時(shí)候,不管關(guān)聯(lián)數(shù)據(jù)有沒有被加載,都會(huì)觸發(fā)數(shù)據(jù)序列化,而如果關(guān)聯(lián)關(guān)系沒有被加載,此時(shí)是一個(gè)HibernateProxy,并不是真實(shí)的數(shù)據(jù),而導(dǎo)致了報(bào)錯(cuò)。
例如這個(gè)Topic Entity:
@Entity @Table(name = "yms_topics") @Getter @Setter @NoArgsConstructor @EntityListeners(AuditingEntityListener.class) @JsonInclude(JsonInclude.Include.NON_EMPTY) @NamedEntityGraphs({ @NamedEntityGraph(name = "topic.all", attributeNodes = { @NamedAttributeNode(value = "author"), @NamedAttributeNode(value = "category") }) }) public class Topic implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(targetEntity = User.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User author; @ManyToOne(targetEntity = TopicCategory.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "category_id") private TopicCategory category; @Column(nullable = false, length = 200) private String title; @Lob @Column(nullable = false, length = 50000) private String content; @CreatedDate private Date createdAt; @LastModifiedDate private Date updatedAt; }
author 和 category 都是多對(duì)一的關(guān)聯(lián),也就是作者和分類,定義的是懶加載LAZY,現(xiàn)在需要分頁取出記錄,Repository 如下:
@EntityGraph(value = "topic.all") PagefindAll(Pageable pageable);
這是關(guān)聯(lián)讀取author和category數(shù)據(jù),沒有任何問題。但是如果有的關(guān)聯(lián)不需要加載,將EntityGraph去掉,就會(huì)報(bào)錯(cuò)。
PagefindAll(Pageable pageable);
究其原因就是HibernateProxy 沒有辦法被序列化,網(wǎng)上有很多的方法,例如JsonIgnoreProperties,這是治標(biāo)不治本的方法
現(xiàn)在要達(dá)到的目標(biāo)是當(dāng)有關(guān)聯(lián)數(shù)據(jù)的時(shí)候序列化,不存在的時(shí)候不返回,或者直接返回Null。
其實(shí)要解決這個(gè)問題很簡(jiǎn)單,那就是使用 Jackson 的一個(gè)包 jackson-datatype-hibernate5。
首先gradle添加依賴:
compile group: "com.fasterxml.jackson.datatype", name: "jackson-datatype-hibernate5", version: "2.9.8"
這個(gè)版本要注意jackson-datatype-hibernateX,根據(jù)Hibernate的版本來定
然后我們要重寫 SpringMvc的 MappingJackson2HttpMessageConverter,將Hibernate5Module這個(gè)Module 注冊(cè)到ObjectMapper。
我們新建一個(gè)WebMvcConfig類,如下:
@Configuration public class WebMvcConfig { @Bean public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = converter.getObjectMapper(); Hibernate5Module hibernate5Module = new Hibernate5Module(); mapper.registerModule(hibernate5Module); mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); return converter; } }
這是一個(gè)Config類,很簡(jiǎn)單
就是注入一個(gè)Bean,類型為MappingJackson2HttpMessageConverter,獲取到ObjectMapper
通過mapper.registerModule(hibernate5Module);注冊(cè)Module
還可以定義時(shí)間如期的序列化格式。
注意如果要讓未加載的時(shí)候完全不輸出,那么在Entity的類級(jí)別注解要使用Empty,例如:@JsonInclude(JsonInclude.Include.NON_EMPTY),不然當(dāng)數(shù)據(jù)為null的時(shí)候會(huì)輸出null。
到這里我們就可以達(dá)到預(yù)期的目的了。
這里可能會(huì)導(dǎo)致spring.jackson的配置失效,以后再行研究。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73540.html
摘要:關(guān)聯(lián)關(guān)系的關(guān)聯(lián)關(guān)系定義上,感覺并不是很靈活,姿勢(shì)也比較難找。如,定義在關(guān)聯(lián)關(guān)系上的參數(shù)可以設(shè)置級(jí)聯(lián)的相關(guān)東西。因?yàn)樾蛄谢瘯?huì)涉及到實(shí)體類關(guān)聯(lián)對(duì)象的獲取,會(huì)觸發(fā)所有的關(guān)聯(lián)關(guān)系。 接(4) - Database 系列. Java Persistence API,可以理解就是 Java 一個(gè)持久化標(biāo)準(zhǔn)或規(guī)范,Spring Data JPA 是對(duì)它的實(shí)現(xiàn)。并且提供多個(gè) JPA 廠商適配,如 Hi...
摘要:什么是作為的子項(xiàng)目,是一款基于的企業(yè)批處理框架。首先,運(yùn)行的基本單位是一個(gè),一個(gè)就做一件批處理的事情。總結(jié)為我們提供了非常實(shí)用的功能,對(duì)批處理場(chǎng)景進(jìn)行了完善的抽象,它不僅能實(shí)現(xiàn)小數(shù)據(jù)的遷移,也能應(yīng)對(duì)大企業(yè)的大數(shù)據(jù)實(shí)踐應(yīng)用。 前言 本文將從0到1講解一個(gè)Spring Batch是如何搭建并運(yùn)行起來的。本教程將講解從一個(gè)文本文件讀取數(shù)據(jù),然后寫入MySQL。 什么是 Spring Batc...
摘要:文章系列從零入門系列之從零入門系列之程序結(jié)構(gòu)設(shè)計(jì)說明前言本篇文章開始代碼實(shí)踐,系統(tǒng)設(shè)計(jì)從底向上展開,因此本篇先介紹如何實(shí)現(xiàn)數(shù)據(jù)庫表實(shí)體類的設(shè)計(jì)實(shí)現(xiàn)。主鍵由數(shù)據(jù)庫自動(dòng)生成主要是自動(dòng)增長(zhǎng)型主鍵由程序控制。 文章系列 【從零入門系列-0】Sprint Boot 之 Hello World 【從零入門系列-1】Sprint Boot 之 程序結(jié)構(gòu)設(shè)計(jì)說明 前言 本篇文章開始代碼實(shí)踐,系統(tǒng)...
摘要:注意,其是在編譯源碼過程中,幫你自動(dòng)生成的。就是說,將極大減少你的代碼總量。注解和類似,區(qū)別在于它會(huì)把所有成員變量默認(rèn)定義為修飾,并且不會(huì)生成方法。不同的日志注解總結(jié)如下上面是注解,下面是編譯后的代碼參考資料下的安裝以及使用簡(jiǎn)介注解介紹 Lombok有什么用 在我們實(shí)體Bean中有大量的Getter/Setter方法以及toString, hashCode等可能不會(huì)用到,但是某些時(shí)候仍...
摘要:忽略該字段的映射省略創(chuàng)建數(shù)據(jù)訪問層接口,需要繼承,第一個(gè)泛型參數(shù)是實(shí)體對(duì)象的名稱,第二個(gè)是主鍵類型。 SpringBoot 是為了簡(jiǎn)化 Spring 應(yīng)用的創(chuàng)建、運(yùn)行、調(diào)試、部署等一系列問題而誕生的產(chǎn)物,自動(dòng)裝配的特性讓我們可以更好的關(guān)注業(yè)務(wù)本身而不是外部的XML配置,我們只需遵循規(guī)范,引入相關(guān)的依賴就可以輕易的搭建出一個(gè) WEB 工程 上一篇介紹了Spring JdbcTempl...
閱讀 1679·2021-11-19 09:40
閱讀 2934·2021-09-24 10:27
閱讀 3221·2021-09-02 15:15
閱讀 1882·2019-08-30 15:54
閱讀 1206·2019-08-30 15:54
閱讀 1375·2019-08-30 13:12
閱讀 637·2019-08-28 18:05
閱讀 2803·2019-08-27 10:53