2013-12-14 2 views
0

나는 데이터베이스에서 영속화 된 두 엔티티가있는 javaEE 애플리케이션을 가지고있다. 두 엔티티 모두 양방향 연관이 있습니다.Circular Json serializing

제 1 개체 :

@Entity 
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Child.class) 
public class Child implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @OneToOne(fetch= FetchType.LAZY) 
    private Father father; 
} 

2 실체는 모두 같은 능숙를 통해 노출되는

@Entity 
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Father.class) 
public class Father implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @OneToOne(fetch= FetchType.LAZY) 
    private Child child; 
} 

:

@Path("father") 
@Stateless 
public class FatherResource{ 

    @Context 
    private UriInfo uri; 

    @Inject FatherDao fatherDao; 

    public FatherResource() { 
    } 

    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    public List<Father> getFathers() { 
     //TODO return proper representation object 
     return fatherDoa.getFathers(); 
    } 
} 

단지에서 아버지 객체를 가져옵니다 DAO도 있습니다 데이터베이스

지금 문제는 순환 json 구조입니다. 다음과 같이 표시됩니다.

{ "id":"1", "child": {"id":"1", "father": {"id":"1", "child":{"id":"1", [...] 

아이를 한 번보고 싶습니다. 내가 얻고 싶은 것은

@JsonIgnoreProperties({"child"}) //above the class 
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id") //above the class 
@JsonIgnore //above the property 

을 : 나는

JDK 7 
JaxRS 
Jackson 
Hibernate/Eclipselink 
Glassfish 4.0 

하지 않는 다른 테스트를 사용하고

{ "id":"1", "child": {"id":"1"}} 

내가 사용하려고 직장 :

(210)
@Entity 
@JsonSerialize 
@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="id", scope=Object.class) 
public class Father implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @OneToOne(fetch= FetchType.LAZY) 
    private Child child; 
} 

ApplicationConfig.java :

public class ApplicationConfig extends Application { 

@Override 
public Set<Class<?>> getClasses() { 
    Set<Class<?>> resources = new java.util.HashSet<Class<?>>(); 
    // following code can be used to customize Jersey 2.0 JSON provider: 

    try { 
     Class jsonProvider = Class.forName("org.glassfish.jersey.jackson.JacksonFeature"); 

    } //... 
//.. 

beans.xml 환경 :

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" 
     bean-discovery-mode="annotated"> 
</beans> 
+0

질문은 무엇입니까? 특히, 당신은 무엇을 기대 했습니까? –

+0

내가 얻고 싶습니다 : { "id": "1", "child": { "id": "1"}} – Laokoon

+0

Jackson의 ObjectIdentity 기능을 사용해 보셨습니까? http://wiki.fasterxml.com/JacksonFeatureObjectIdentity –

답변

1

당신은 목록을 반환하기 전에 null로 father를 설정하는 루프를 작성할 수 있습니다. 그렇게하면 순환 데이터 구조를 JSON 시리얼 라이저에 제공하지 않게됩니다.

이 솔루션은 매우 깨끗해 보이지 않을 수도 있지만 작동하지만 다른 누구도이 질문에 대답하지 못했기 때문에 언급 할 가치가 있다고 생각했습니다.

0

다음은 문제를 해결하고 해결하는 예제입니다. Jackson은 재귀를 직렬화 할 수 있습니다. 이것 좀 봐 :

3 POJOs (A, B, C) 및 테스트. Jackson 2.2.3으로 테스트되었습니다. 여기

import com.fasterxml.jackson.annotation.JsonIdentityInfo; 
import com.fasterxml.jackson.annotation.ObjectIdGenerators; 

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 
public class RecClassA { 

    private RecClassA mySelf; 
    private RecClassB b; 

    private String value = "AV"; 

    public String getValue() { 
     return value; 
    } 

    public void setValue(String value) { 
     this.value = value; 
    } 

    public RecClassA getMySelf() { 
     return mySelf; 
    } 

    public void setMySelf(RecClassA mySelf) { 
     this.mySelf = mySelf; 
    } 

    public RecClassB getB() { 
     return b; 
    } 

    public void setB(RecClassB b) { 
     this.b = b; 
    } 

} 

import com.fasterxml.jackson.annotation.JsonIdentityInfo; 
import com.fasterxml.jackson.annotation.ObjectIdGenerators; 

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 
public class RecClassB { 

    private String value = "BV"; 
    private RecClassC c; 
    private RecClassA a; 

    public String getValue() { 
     return value; 
    } 

    public void setValue(String value) { 
     this.value = value; 
    } 

    public RecClassC getC() { 
     return c; 
    } 

    public void setC(RecClassC c) { 
     this.c = c; 
    } 

    public RecClassA getA() { 
     return a; 
    } 

    public void setA(RecClassA a) { 
     this.a = a; 
    } 

} 

import com.fasterxml.jackson.annotation.JsonIdentityInfo; 
import com.fasterxml.jackson.annotation.ObjectIdGenerators; 

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 
public class RecClassC { 

    private String value = "CV"; 
    private RecClassA a; 

    public String getValue() { 
     return value; 
    } 

    public void setValue(String value) { 
     this.value = value; 
    } 

    public RecClassA getA() { 
     return a; 
    } 

    public void setA(RecClassA a) { 
     this.a = a; 
    } 

} 

import org.testng.annotations.Test; 

import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class ObjectMapperRecursionTest { 

    private ObjectMapper om = new ObjectMapper(); 

    @Test 
    public void simpleWriteTest() throws JsonProcessingException{ 
     RecClassA a = new RecClassA(); 

     String result = om.writeValueAsString(a); 
     System.out.println("simpleWriteTest: " + result); 
    } 

    @Test 
    public void simpleRecursionWriteTest() throws JsonProcessingException{ 
     RecClassA a = new RecClassA(); 
     a.setMySelf(a); 
     String result = om.writeValueAsString(a); 
     System.out.println("simpleRecursionWriteTest: " + result); 
    } 

    @Test 
    public void abbaRecursionWriteTest() throws JsonProcessingException{ 
     RecClassA a = new RecClassA(); 
     RecClassB b = new RecClassB(); 

     a.setB(b); 
     b.setA(a); 

     String result = om.writeValueAsString(a); 
     System.out.println("abbaRecursionWriteTest: " + result); 
    } 

    @Test 
    public void abcaRecursionWriteTest() throws JsonProcessingException{ 
     RecClassA a = new RecClassA(); 
     RecClassB b = new RecClassB(); 
     RecClassC c = new RecClassC(); 

     a.setB(b); 
     b.setC(c); 
     c.setA(a); 

     String result = om.writeValueAsString(c); 
     System.out.println("abcaRecursionWriteTest: " + result); 
    } 

} 

시험의 결과 :

abbaRecursionWriteTest: {"@id":1,"mySelf":null,"b":{"@id":2,"value":"BV","c":null,"a":1},"value":"AV"} 
abcaRecursionWriteTest: {"@id":1,"value":"CV","a":{"@id":2,"mySelf":null,"b":{"@id":3,"value":"BV","c":1,"a":null},"value":"AV"}} 
simpleRecursionWriteTest: {"@id":1,"mySelf":1,"b":null,"value":"AV"} 
simpleWriteTest: {"@id":1,"mySelf":null,"b":null,"value":"AV"}