有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate HttpMessageNotWritableException

我目前正在SpringMVC4.2.3中使用Hibernate4.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;
}

......
}

在{}中,我设置:

@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的会话从未过期


共 (1) 个答案

  1. # 1 楼答案

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

    你能做的事情很少

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

    这个answer有更好的方法