【问题标题】:Spring MVC, Domain Objects & @JsonIgnoreSpring MVC、领域对象和@JsonIgnore
【发布时间】:2012-03-11 18:09:04
【问题描述】:

我正在使用 Spring MVC 3 并尝试使用我的域对象返回 json 响应。问题是由于双向关系和自我关系(员工报告给员工),我收到 JsonMappingException: Infinite recursion

我尝试使用 @JsonIgnore 但 spring/jackson 仍然尝试包含属性 (Infinite Recursion with Jackson JSON and Hibernate JPA issue)

知道为什么@JsonIgnore 没有加入吗?

我知道传输对象或 jsonviews 是一种更好的方法,但我仍然想在继续之前深入了解。

客户.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)

【问题讨论】:

  • 堆栈跟踪是什么样的?
  • @mattb - 我在问题中添加了堆栈跟踪
  • 正如 James DW 在下面提到的堆栈跟踪中提到的未包含在这篇文章中的类。 Employee 和 Office 也有 @JsonIgnore 吗?
  • 是的,我向所有关系获取器添加了@jsonIgnore。返回客户列表时出现此异常。

标签: java json hibernate spring-mvc


【解决方案1】:

根据您的例外情况,循环引用似乎来自您的 Office 类,此处未列出。

我真的会考虑创建那些传输对象。除了使您的 JPA 模型复杂化之外,您还将您的域耦合到一组非常具体的、非域的类。

如果您想更改 JSON 解析实现,则必须更改域对象。

【讨论】:

  • 是的,有不止一个双向关系(客户 > 员工 > 办公室)。我会选择 TO,但不明白为什么 @JsonIgore 在这种情况下不起作用
【解决方案2】:

使用@jsonManagedRefrence 和@JsonBackRefrence, 我的问题就这样解决了。

【讨论】:

    猜你喜欢
    • 2010-11-07
    • 2010-10-01
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    相关资源
    最近更新 更多