2012-10-16 6 views
7

Gibt es eine Möglichkeit, LAZY das Objekt zu laden und deserialisieren mit der ID anstelle des POJO-Objekts.deserialize lazy loading in hibernate und jackson

Ich habe 2 Klasse, die durch eine Viele-zu-viele-Beziehung verbunden sind.

So etwas wie dieser

public class User { 
    @Id 
    @JsonProperty 
    public long id; 

    @ManyToMany(
      fetch = FetchType.EAGER, 
    ) 
    @JoinTable(
      name = "User_EntityType", 
      joinColumns = @JoinColumn(name = "user_id"), 
      inverseJoinColumns = @JoinColumn(name = "type_id") 
    ) 
    @JsonProperty 
    public Set<Type> types; 

} 

public class Type { 
    @Id 
    @JsonProperty 
    public long id; 

    @ManyToMany(
      fetch = FetchType.EAGER, 
      mappedBy = "types", 
      targetEntity = User.class 
    ) 
    @JsonProperty 
    public Set<User> users; 
} 

Der Datentyp funktioniert gut. Ich kann mit Hibernate ohne Problem schreiben und lesen.

Ich möchte jedoch in der Lage sein, ein Benutzerobjekt mit einer REST-API zurückzugeben, also verwende ich Jackson, um es zu deserialisieren. Das Problem ist, wenn ich das mache, deserialisiert es jedes Type in dem User-Objekt, das andere Type-Objekte enthält, und es erzeugt ein riesiges Durcheinander.

Ist es möglich, stattdessen den Satz von Long Type IDs anstelle von Set of Type zurückgeben?

Antwort

4

Ja, es ist möglich, wenn Sie Jackson 2.0 verwenden, mit der Objektidentität-Funktion.

Wenn Sie eine Klasse mit der @JsonIdentityInfo Annotation annotieren, wird Jackson das Objekt nur einmal ausgeben; Nachfolgende Referenzen verwenden stattdessen die ID. Ihre Typen werden daher als IDs serialisiert, solange die Typen einmal ausgegeben wurden. Beim Deserialisieren von Jackson werden die IDs wieder in Objekte umgewandelt.

In Ihrem Fall denke ich, Sie Ihre Art Klasse wie diese mit Anmerkungen versehen müßten:

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id") 
public class Type { 
    ... 
} 

Siehe http://wiki.fasterxml.com/JacksonFeatureObjectIdentity für Details, wie diese Funktion zu nutzen.

0

Ich hatte dieses Problem auch in meinen JAX-RS-Endpunkten, die Hibernate-Entitäten mithilfe von Jacksons Object Mappers serialisieren und bereitstellen müssen. Die Option, Lösungen wie @JsonIgnore oder @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class,... zu verwenden, war für mich keine Option, da erstere bedeuten würde, dass das relationale Feld aus der serialisierten Ausgabe ausgelassen wird, und die spätere Methode sortierte das Problem nicht, egal was passiert.

So, das war meine Lösung die folgende Flagge auf dem Mapper vor tut die tatsächliche Serialisierung zu setzen:

ObjectMapper objMapper = new ObjectMapper(); 
objMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); 

Auf diese Weise gibt es keinen Versuch war relationale Objekte zu füllen, wurden stattdessen ihre ids intakt gelassen, und so konnte ich die Flagge fetch = FetchType.LAZY auf meinen relationalen Feldern behalten.