2014-04-18 42 views
4

我很難搞清楚如何在Web應用程序中正確定義和註釋模型,以便它們可以有效地用於Web界面和REST Web服務。這是給我找麻煩的關係的簡化版本:序列化與Spring MVC,Jackson和Hibernate的多對多關係的對象

Post模型:

@Entity 
@Table(name = "POST") 
public class Post implements Serializable { 

    @Id 
    @Column(name = "POST_ID") 
    @GeneratedValue(strategy-GenerationType.AUTO) 
    private Integer postId; 

    @Column(name = "POST_BODY") 
    private String postBody; 

    @ManyToMany(fetch = FetchType.EAGER) 
    @Cascade({CascadeType.SAVE_UPDATE}) 
    @JoinTable(name = "POST_TAGS", 
      joinColumns={@JoinColumn(name="POST_ID")}, 
      inverseJoinColumns={@JoinColumn(name="TAG_ID")}) 
    private Set<Tag> tags = new HashSet<Tag>(); 

    //Getters and setters... 
} 

標籤模式

@Entity 
@Table(name = "TAG") 
public class Tag implements Serializable { 

    @Id 
    @Column(name = "TAG_ID") 
    @GeneratedValue(strategy-GenerationType.AUTO) 
    private Integer tagId; 

    @Column(name = "TAG_NAME") 
    private String tagName; 

    @ManyToMany(fetch = FetchType.EAGER, mappedBy="tags") 
    private Set<Post> posts = new HashSet<Post>(); 

    //Getters and setters... 
} 

我有獲取一個網絡服務控制器的方法所有帖子和一個獲取所有標籤的方法。理想情況下,每種方法都應該返回目標類和被引用類的列表。例如:

[{ 
    postId: 1, 
    postBody: "Hello world!", 
    tags: [{ 
     tagId: 1, 
     tagName: "hello" 
    },{ 
     tagId: 2, 
     tagName: "message" 
    }] 
}, { 
    postId: 2, 
    .... 
}] 

但我風看到的內容是無限遞歸,作爲返回的標籤爲每個職位檢索其相關聯的支柱,其檢索及其關聯的標記等,以無窮大。我曾嘗試在我的類的getter方法上使用@JsonIgnore,但後來我不再獲取引用的對象。我曾嘗試使用@JsonIdentityInfo將ID添加到我的對象,但是我仍然得到遞歸,但僅限於檢索到的對象之間的所有引用都耗盡的點。我似乎無法找到解釋如何處理這些情況的任何文檔,這看起來很常見。

回答

0

您可以對此使用Jackson的註釋(@JsonManagedReference@JsonBackReference)。

檢查http://wiki.fasterxml.com/JacksonFeatureBiDirReferences

或者你可以寫自己的串行器與跟蹤你已經連載了什麼,這是我落得這樣做的時候,我不得不使用GSON而不是傑克遜。

+0

雖然這個例子中'@ JsonManagedReference'和'@ JsonBackReference'如何工作?根據上下文,「Post」和「Tag」都可以是父母或孩子。 – woemler

+0

嗯,我想我錯過了這部分的問題。您仍然可以爲這些對象創建自己的序列化程序,然後跟蹤已經序列化的內容。 –

0

我寫了傑克遜休眠模塊的詳細用法(https://github.com/FasterXML/jackson-datatype-hibernate) 對不起,我的英文不好。如下所示,如果我們使用默認的jackson + jackson-databind模塊 - 我們在多對多序列化方面遇到了一些麻煩。如果我們不使用@JsonIgnore + @JsonIdentityInfo註釋,這是一個「無限循環」。如果我們同時使用它們,它就是「ID作爲結果」。

解決煩惱的最佳方法 - 使用模塊。 1.添加行家DEP

<dependency> 
     <groupId>com.fasterxml.jackson.datatype</groupId> 
     <artifactId>jackson-datatype-hibernate4</artifactId> 
     <version>${jackson.version}</version> 
</dependency> 
  • 創建和使用定製ObjectMapper
  • HibernateAwareObjectMapper.java

    import com.fasterxml.jackson.databind.ObjectMapper; 
    import com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module; 
    
    public class HibernateAwareObjectMapper extends ObjectMapper { 
    
        public HibernateAwareObjectMapper() { 
         registerModule(new Hibernate4Module()); 
        } 
    } 
    

    3.使用此映射器在春季XML配置

    <mvc:annotation-driven> 
         <mvc:message-converters> 
          <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
           <property name="objectMapper"> 
            <bean class="path.HibernateAwareObjectMapper"/> 
           </property> 
          </bean> 
         </mvc:message-converters> 
        </mvc:annotation-driven> 
    
    1. 向實體字段添加註釋。

    郵政實體不需要註釋。

    標記實體爲修復「無限循環」錯誤添加@JsonIgnore註釋。

    此外,我們可以將EAGER更改爲LAZY fetchtype。通過ObjectMapper config獲取規則FORCE_LAZY_LOADING 更多關於javadoc的信息(http://fasterxml.github.io/jackson-datatype-hibernate/javadoc/h4-2.4/com/fasterxml/jackson/datatype/hibernate4/Hibernate4Module.Feature.html#FORCE_LAZY_LOADING)或github上的代碼