2012-11-15 1 views
0

이 버그는 회사가 다시 묻는 워크 시트를 요청하는 재귀 버그 인 것 같습니다. 어느 것이 .... 드리프트가되는지. 이 인터넷을 검색하고 오버플로를 수행하여 오류가 발생하는 이유를 알아 냈습니다. 그러나 솔루션은 항상 자체 파서를 작성하거나 flexjson 또는 다른 것을 사용합니다. 나는 이것에 대한 해결책이 있는지 알고 싶다. 놀이가 꽤 대중적이기 때문에 분명히 사람들이 한 번의 조작으로 게시물과 코멘트를 가져오고 있는가? 그렇지 않은가?GSON 오류입니다.

json 파서를 교체하거나 직접 작성하지 않고도이를 해결할 수있는 솔루션이 필요합니다.

Company.java

package models; 

import java.util.*; 
import javax.persistence.*; 

import play.db.jpa.*; 

@Entity 
public class Company extends Model { 
    public String name; 
    public String address; 
    public String city; 
    public String zipcode; 
    public String country; 
    public String phonenumber; 
    public String website; 
    public String footer; 
    public String maincontactperson; 
    public String email; 
    public String password; 
    public Blob logo; 
    @OneToMany(mappedBy = "company", cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) 
    public List<Worksheet> worksheets; 


    } 

} 

Worksheet.java

package models; 

import java.util.*; 
import javax.persistence.*; 

import play.db.jpa.*; 

@Entity 
public class Worksheet extends Model { 
    public String contactname; 
    public String name; 
    public String address; 
    public String phonenumber; 
    public String city; 
    public String email; 
    public String partnumber; 
    @Lob 
    public String partdescription; 
    public String password; 
    public Date due_date; 
    public Date in_date; 
    @Lob 
    public String notes; 
    @ManyToOne(cascade=CascadeType.ALL) 
    public Company company; 
... 
} 

내 컨트롤러에서, 난 그냥이 실행이있는 경우이 작동

List<Company> companies = Company.FindAll(); 
renderJSON(companies); 

을 일하는 사람 없음 ts이지만 일단 워크 시트가 있으면 마일 오류 메시지와 함께 충돌합니다. 여기의 상단입니다이 버그가 아닙니다

00:31:02,623 ERROR ~ 

@6cbn7gi1o 
Internal Server Error (500) for request POST /companies/login 

Execution exception 
InvocationTargetException occured : null 

play.exceptions.JavaExecutionException 
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:239) 
    at Invocation.HTTP Request(Play!) 
Caused by: java.lang.reflect.InvocationTargetException 
    at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:557) 
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:508) 
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:484) 
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:479) 
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161) 
    ... 1 more 
Caused by: java.lang.StackOverflowError 
    at java.util.Date.getTimeImpl(Date.java:870) 
    at java.util.Date.getTime(Date.java:866) 
    at java.sql.Timestamp.getTime(Timestamp.java:126) 
    at java.util.Calendar.setTime(Calendar.java:1076) 
    at java.text.SimpleDateFormat.format(SimpleDateFormat.java:875) 
    at java.text.SimpleDateFormat.format(SimpleDateFormat.java:868) 
    at java.text.DateFormat.format(DateFormat.java:316) 
    at com.google.gson.internal.bind.DateTypeAdapter.write(DateTypeAdapter.java:90) 
    at com.google.gson.internal.bind.DateTypeAdapter.write(DateTypeAdapter.java:41) 
    at com.google.gson.internal.bind.TypeAdapters$22$1.write(TypeAdapters.java:522) 
    at com.google.gson.internal.bind.TypeAdapters$22$1.write(TypeAdapters.java:515) 
.... 

    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
    at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:879) 
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
+0

GSON의 JsonSerializer에서 상속 된 고유 한 JsonSerializer를 작성할 수 있습니다. 이 경우 JSON을 직접 구문 분석 할 필요가 없습니다. 시리얼 라이저에서 원하지 않는 필드 만 '제외'하십시오. 예를 들면 다음과 같습니다. http://stackoverflow.com/questions/9040060/playframework-json-template-list-ojects-with-foreach/9044569#9044569 – dwi2

답변

3

IMHO, 당신은 모델에 재귀를 가지고 프레임 워크는 정말 모델을 직렬화하는 방법을 자동으로 알 수 없다.

나는 이것을 @Expose 어노테이션으로 보통 해결한다. 주석에 제안

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); 
    String json = gson.toJson(your_model_instance); 

가 선택적으로 당신은 또한 JsonSerializer 인터페이스를 구현할 수 있습니다 : 당신이 당신의 직렬화 된 JSON에 표시하고이 같은 일을 수행하는 도우미 메서드를 만들 모든 구성원에 추가합니다.

+0

무한정을 방지하기 위해 Gson에게 1 단계 만 내려가는 방법은 없습니다. 루프? 레일스는 내가 기대하는 바를 수행하며 기대치는 거기에서 나온다. CakePHP에서는 얼마나 많은 레벨을 재귀 적으로 정의 할 것인지를 정의합니다. 그러나 Play에는 그와 같은 것이 없습니다. 나는 해결책을 찾기 위해 노력하면서, 그리고 나 자신의 시리얼 라이저 (serializer) 등을하기 전에, 여기에서 어떤 것도 무시하지 않을 것이다. –

+0

내가 아는 한 그것은 불가능합니다. Gson 세부 정보는 http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/index.html – nylund

+0

내 모델에 주석을다는 팬이 아닙니다. 모든 호출에 대해 해당 제외 패턴을 고수하여 flexjson.JSONSerializer를 사용합니다. flexjson을 사용하면 '*'제외 패턴을 사용하여 호출과 관련된 json 데이터 만 전달할 수 있습니다. – seePatCode

0

another question에서 순환 참조 문제를 멋지게 해결할 것으로 보이는 (모델 클래스 수정없이) this class에 대한 링크를 찾았습니다.

예를 들어 링크 된 질문에 대한 승인 된 답변을 참조하십시오.