2014-11-24 57 views
3

我試圖轉換以下POJO到JSON在@RestController傑克遜Spring MVC的重複的嵌套對象不反序列化

@Entity 
@Table(name="user_location") 
@NamedQuery(name="UserLocation.findAll", query="SELECT u FROM UserLocation u") 
public class UserLocation implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    private String addr1; 

    private String addr2; 

    private String landmark; 

    private BigDecimal lat; 

    private BigDecimal lng; 

    private String zipcode; 

    //bi-directional many-to-one association to City 
    @ManyToOne 
    private City city; 

    //bi-directional many-to-one association to State 
    @ManyToOne 
    private State state; 

    public UserLocation() { 
    } 

    //Getter - Setters 

} 

嵌套City.java情況如下:

@Entity 
@NamedQuery(name="City.findAll", query="SELECT c FROM City c") 
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property="@id", scope = City.class) 
public class City implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    private String name; 

    //bi-directional many-to-one association to State 
    @ManyToOne 
    @JsonIgnore 
    private State state; 

    //bi-directional many-to-one association to UserLocation 
    @OneToMany(mappedBy="city") 
    @JsonIgnore 
    private List<UserLocation> userLocations; 

    public City() { 
    } 

    public int getId() { 
     return this.id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @JsonProperty("state") 
    public State getState() { 
     return this.state; 
    } 

    public void setState(State state) { 
     this.state = state; 
    } 


    public List<UserLocation> getUserLocations() { 
     return this.userLocations; 
    } 

    public void setUserLocations(List<UserLocation> userLocations) { 
     this.userLocations = userLocations; 
    } 

    public UserLocation addUserLocation(UserLocation userLocation) { 
     getUserLocations().add(userLocation); 
     userLocation.setCity(this); 

     return userLocation; 
    } 

    public UserLocation removeUserLocation(UserLocation userLocation) { 
     getUserLocations().remove(userLocation); 
     userLocation.setCity(null); 

     return userLocation; 
    } 

} 

另一個嵌套類State.java如下:

@Entity 
@NamedQuery(name="State.findAll", query="SELECT s FROM State s") 
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property="@id", scope = State.class) 
public class State implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    private String name; 

    //bi-directional many-to-one association to City 
    @OneToMany(mappedBy="state") 
    @JsonIgnore 
    private List<City> cities; 

    //bi-directional many-to-one association to UserLocation 
    @OneToMany(mappedBy="state") 
    @JsonIgnore 
    private List<UserLocation> userLocations; 

    public State() { 
    } 

    public int getId() { 
     return this.id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public List<City> getCities() { 
     return this.cities; 
    } 

    public void setCities(List<City> cities) { 
     this.cities = cities; 
    } 

    public City addCity(City city) { 
     getCities().add(city); 
     city.setState(this); 

     return city; 
    } 

    public City removeCity(City city) { 
     getCities().remove(city); 
     city.setState(null); 

     return city; 
    } 

    public List<UserLocation> getUserLocations() { 
     return this.userLocations; 
    } 

    public void setUserLocations(List<UserLocation> userLocations) { 
     this.userLocations = userLocations; 
    } 

    public UserLocation addUserLocation(UserLocation userLocation) { 
     getUserLocations().add(userLocation); 
     userLocation.setState(this); 

     return userLocation; 
    } 

    public UserLocation removeUserLocation(UserLocation userLocation) { 
     getUserLocations().remove(userLocation); 
     userLocation.setState(null); 

     return userLocation; 
    } 

} 

JSON從UserLocation.j AVA是如下:

{ 
    id: 1, 
    addr1: "11905 Technology", 
    addr2: "Eden Prairie", 
    landmark: null, 
    lat: null, 
    lng: null, 
    zipcode: "55344", 
    city: { 
     @id: 1, 
     id: 2, 
     name: "Westborough", 
     state: { 
      @id: 1, 
      id: 2, 
      name: "MA" 
     } 
    }, 
    state: 1 
} 

正如你所看到的,State對象來作爲內部city整個對象。但外state(的「用戶位置is showing just an id of國家object. I need to have a same狀態object as that of city`而不僅僅是ID。

我是比較新的API傑克遜財產。請指點哪一種方法,我應該遵循來實現這一要求。

感謝

回答

5

這是傑克遜如何設計JsonIdentityInfo標註邏輯。

* Annotation used for indicating that values of annotated type 
* or property should be serializing so that instances either 
* contain additional object identifier (in addition actual object 
* properties), or as a reference that consists of an object id 
* that refers to a full serialization. In practice this is done 
* by serializing the first instance as full object and object 
* identity, and other references to the object as reference values. 

傑克遜將首先運行完整的系列化TI我和唯一的id將被序列化,當它第二次找到對象。

因此,有兩種方式可以如何解決:

1)你可以簡單的刪除@JsonIdentityInfo註釋和傑克遜將序列化對象如你預期,但它會從響應刪除@id領域。這可能很好,因爲你仍然會有'id'屬性。

2)我覺得你可以簡單地重組你的對象並刪除一些引用。無論如何,我會說做這些改變是很好的。首先,您可以從UserLocation中刪除對狀態的引用。我想說,因爲州屬於城市,所以沒有必要讓用戶位置類中的國家。 通過這樣做,您將訪問城市狀態,並解決您的問題。 另外我會從City類以及State類中刪除對userLocations列表的引用。

它看起來像:

用戶位置有城,沒有國家。

市擁有國家,沒有userLocations

國家沒有userLocations以及城市。

希望這有助於

+0

感謝您的建議。我按照你的建議刪除了不必要的映射。 – hemu 2014-11-25 05:55:12

+0

很久以前我在尋找這個答案...感謝您的解釋 – 2016-08-25 17:50:12

0

首先請刪除您State.java和City.java

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property="@id", scope = State.class) 

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property="@id", scope = City.class) 

無需這些註解和RestController添加註解返回類型爲用戶位置@ResponseBody。它會給你這個班的學生。