2012-03-11 25 views
2

私はSpring MVC 3で作業していて、自分のドメインオブジェクトを使用してjson応答を返そうとしています。問題は、双方向の関係と自己関係(従業員reportsTo従業員)のため、私はJsonMappingExceptionを受けています:無限再帰Spring MVC、ドメインオブジェクトと@JsonIgnore

@JsonIgnoreを使用しようとしましたが、spring/jacksonは属性(Infinite Recursion with Jackson JSON and Hibernate JPA issue

なぜ@JsonIgnoreが蹴られないのですか?

転送オブジェクトやjsonviewsがこれを行うためのより良い方法であることはわかっていますが、私は移動する前にこのままにしたいと思っています。

Customer.java

@Entity 
@NamedQueries({ 
    @NamedQuery(name="Customer.findByName", query="from Customer cust where cust.customerName like :customerName"), 
    @NamedQuery(name="Customer.findByAccountNumber", query="from Customer cust where cust.accountNumber = :accountNumber"), 
    }) 
public class Customer implements DomainObject { 
    private Long id; 
    private String accountNumber; 
    private String customerName; 
    private CustomerDerived derived; 
    private Employee salesRep; 
    private Set<Order> orders = new HashSet<Order>(); 

    @Id 
    @GeneratedValue 
    @Column(name="Id") 
    public Long getId() { return id; } 
    public void setId(Long id) { this.id=id; } 

    @Column(unique=true) 
    public String getAccountNumber() {return accountNumber;} 
    public void setAccountNumber(String accountNumber) {this.accountNumber = accountNumber; } 

    public String getCustomerName() { return customerName; } 
    public void setCustomerName(String customerName) { this.customerName = customerName;} 

    @JsonIgnore 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name="salesRepEmployeeId") 
    public Employee getSalesRep() { return salesRep; } 
    public void setSalesRep(Employee salesRep) {this.salesRep = salesRep;} 

    @JsonIgnore 
    @OneToMany(mappedBy="customer", fetch = FetchType.LAZY) 
    public Set<Order> getOrders() { return orders; } 
    public void setOrders(Set<Order> orders) {this.orders = orders; } 

    @OneToOne 
    @PrimaryKeyJoinColumn(name="customerId") 
    public CustomerDerived getDerived() {return derived;} 
    public void setDerived(CustomerDerived derived) {this.derived = derived;} 

} 

TestController.java

@Controller 
@RequestMapping(value="/test") 
public class TestController { 
    private CustomerDao customerDao; 

    @Autowired 
    public TestController(CustomerDao customerDao){ 
     this.customerDao=customerDao; 
    } 

    @RequestMapping(value="/getAll", method=RequestMethod.GET) 
    public String getAll(Model model){ 
     List<Customer> customers = customerDao.findAll(); 
     model.addAttribute("customers", customers); 
     return "testresult"; 
    } 

    @RequestMapping(value="/searchByName/{name}", method=RequestMethod.GET) 
    public @ResponseBody List<Customer> search(@PathVariable String name){ 
     List<Customer> customers = customerDao.findByName(name); 
     System.out.println("got customers"); 
     return customers; 
    } 
} 

スタックトレースあなたの例外に基づき

SEVERE: Servlet.service() for servlet orderWeb threw exception 
org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.mike.orderapp.domain.Office["employees"]->org.hibernate.collection.PersistentSet[0]->com.mike.orderapp.domain.Employee_$$_javassist_0["office"]->com.mike.orderapp.domain.Office["employees"]->org.hibernate.collection.PersistentSet[0]->com.mike.orderapp.domain.Employee_$$_javassist_0["office"]->com.mike.orderapp.domain.Office["employees"]->org.hibernate.collection.PersistentSet[0]- 
...... 
>com.mike.orderapp.domain.Employee_$$_javassist_0["office"]->com.mike.orderapp.domain.Office["employees"]) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:164) 
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) 
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) 
+0

スタックトレースはどのように見えますか? –

+0

@mattb - 質問 – miklesw

+0

にstacktraceを追加しました.James DWはstacktraceの下にこの投稿に含まれていないクラスを記述しています。従業員とオフィスには@JsonIgnoreもありますか? –

答えて

1

循環参照ではありません、あなたのオフィスクラスからあるように見えますここに記載されている。

私は実際にこれらの転送オブジェクトの作成を検討します。 JPAモデルを複雑にすることに加えて、ドメインを非常に特殊なドメイン以外のクラスセットに結合しています。

JSON解析実装を変更したい場合は、ドメインオブジェクトを変更する必要があります。

+1

うーん、2つ以上の双方向の関係(顧客>従業員>オフィス)がある。 私はTOに行くだろうが、この場合@JsonIgoreがなぜ機能しないのか理解できない – miklesw

0

@jsonManagedRefrenceと@JsonBackRefrenceを使用すると、 私の問題はこれで解決しました。

関連する問題