2012-03-11 84 views
2

我使用Spring MVC 3個工作,並試圖用我的域對象返回一個JSON響應。問題是由於雙向關係和自我關係(員工reportsTo員工),我收到JsonMappingException:無限遞歸Spring MVC中,域對象和@JsonIgnore

我試過使用@JsonIgnore,但彈簧/傑克遜仍試圖包含屬性(Infinite Recursion with Jackson JSON and Hibernate JPA issue

任何想法,爲什麼@JsonIgnore中沒有踢?

我知道,傳輸對象或jsonviews這樣做的更好的辦法,但i'de還是喜歡去的這條底線之前,我繼續前進。

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

stacktrace是什麼樣的? – 2012-03-11 18:13:51

+0

@mattb - 我在詹姆斯DW提到的不包括在這篇文章中的堆棧跟蹤提到類中提到了 – miklesw 2012-03-11 19:10:27

+0

這個問題的stacktrace。僱員和辦公室還有@JsonIgnore嗎? – 2012-03-11 22:25:30

回答

1

根據您的例外,它看起來像循環引用是從您的Office類,這是不在此列出。

我真的會考慮創建的傳輸對象。除了使您的JPA模型複雜化之外,您還將您的域耦合到非特定的非域的一組類。

如果你想改變你的JSON解析實現你必須改變你的域對象。

+1

是的,有不止一個雙向關係(客戶>員工>辦公室).. 我會去的TO,但不明白爲什麼@JsonIgore不在這種情況下工作 – miklesw 2012-03-11 22:28:47

0

使用@jsonManagedRefrence和@JsonBackRefrence, 我的問題得到了這個解決。