2012-03-11 80 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, 我的问题得到了这个解决。