【问题标题】:Hibernate HttpMessageNotWritableException休眠 HttpMessageNotWritableException
【发布时间】:2016-08-18 06:18:20
【问题描述】:

我目前在 Spring MVC 4.2.3 中使用 Hibernate 4.3.5。我有两个模型UserClient,其中UseridClient 的外键。

User 类中:

@Repository
@Transactional
public class UserDAOImpl implements UserDAO {

@Autowired
private SessionFactory sessionFactory;

protected SessionFactory getSessionFactory() {
    try {
        return (SessionFactory) new InitialContext().lookup("SessionFactory");
    } catch (Exception e) {
        log.error("Could not locate SessionFactory in JNDI", e);
        throw new IllegalStateException("Could not locate SessionFactory in JNDI");
    }
}

@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
public Set<Client> getClients() {
    return this.clients;
}

......
}

Client,我设置:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
public User getUser() {
    return this.user;
}

SessionFactoryroot-context.xml 中定义。这样,我应该可以从分离的User对象中获取clients,对吧?但是,当我运行这段代码时:

results.addAll(userDAO.findById(id).getClients());

它返回了以下异常:

WARN : org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError) (through reference chain: com.hersbitcloud.cancercloud.models.Client["user"]->com.hersbitcloud.cancercloud.models.User["clientss"]->org.hibernate.collection.internal.PersistentSet[0]->com.hersbitcloud.cancercloud.models.Client["user"]->com.hersbitcloud.cancercloud.models.User["clients"]->org.hibernate.collection.internal.PersistentSet[0]-
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed

堆栈跟踪非常长,我认为这意味着当我获得User 时,它同时获取Client,因为它是EAGER。然后User对象被再次获取为Client的内部对象,即使它被设置为LAZY。这个过程来来回回,永不停息。

我了解LAZY 仅在会话中获取内容。我的问题是,为什么与User 的会话永不过期?

【问题讨论】:

标签: java spring hibernate


【解决方案1】:

这是因为您的模型(实体)具有双向映射。 当 Jackson 尝试序列化对象时,它面临user.getClients()[0].getUser().getClients().... 递归链。因为你直接在表现层使用实体。

你可以做一些事情。

  1. 使用 DTO
  2. 直接在您的实体上使用 @JsonIgnore(我不喜欢 DAO/MVC 混合)
  3. 可能有更多选择

这个answer 有更好的方法来做到这一点

【讨论】:

  • 它解决了问题,谢谢。我认为问题在于杰克逊数据映射。它试图检索所有内容。如果使用 DTO,一切都很好。顺便说一句,@JsonIgnore 也可以正常工作。
猜你喜欢
  • 2011-12-16
  • 2021-10-21
  • 2015-02-08
  • 2019-04-18
  • 2017-02-06
  • 2017-05-18
  • 2017-09-19
  • 2013-10-19
  • 2010-10-14
相关资源
最近更新 更多