当前位置: 首页 > 知识库问答 >
问题:

Hibernate和Jackson(java.lang.IllegalStateException:响应提交后无法调用sendError())

阎麒
2023-03-14

你好,Hibernate和Jackson有问题。有两个POJO

@Entity
@Table(name = "USERS")
public class User implements Serializable {
static final long serialVersionUID = 4235637833262722256L;

@Id
@GeneratedValue
private int id;

@Column(name = "CREATION_DATE")
private Date creationDate;

@Column(name = "FIRST_NAME")
private String firstName;

@Column(name = "LAST_NAME")
private String lastName;

@Version
@Column(name = "VERSION")
private int version;

@Column(name = "E_MAIL")
private String email;

@Column(name = "ENABLED")
private boolean enabled;

@Column(name = "LOGIN")
private String login;

@Column(name = "PASSWORD")
private String password;

@JsonManagedReference("role")
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL,fetch = FetchType.EAGER)
private Set<UserRole> userRole;

为Spring Security集成而设计的用户及其角色。

@Entity
@Table(name = "USER_ROLES")
public class UserRole {

@Version
@Column(name = "VERSION")
int version;
@Id
@GeneratedValue
private int id;

@JsonBackReference("role")
@ManyToOne()
@JoinColumn(name = "USER_ID", referencedColumnName = "ID")
private User user;

@Column(name = "ROLE")
private String role;

还有一个控制器,通过Jackson从用户Json生成。With方法

  @RequestMapping(value = "/login", method = RequestMethod.GET, produces = "application/json")
private @ResponseBody User checkLoginAvailability(@RequestParam String login) {
    User user = appContext.getUserService().readUserByLogin(login);
    if (user != null) {
        return user;
    }
    return new User();
}

当此方法返回不带null字段的用户时,将抛出:

26-Oct-2014 14:31:17.652 WARNING [http-nio-8080-exec-4] 
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.doResolveException 
Handling of [org.springframework.http.converter.HttpMessageNotWritableException]
resulted Exception java.lang.IllegalStateException: Cannot call sendError() after the response has been committed

当我添加@OneTo很多时,这个问题就出现了(mep dBy="user", cascade=CascadeType. ALL, fetch=FetchType. EAGER),以前它只是fetch=FetchType. EAGER,但我无法用他的角色保存User,在这种情况下,表USER_ROLE是空的。我在杰克逊的某个地方无限循环中红色了一些解决方案,添加了一些anotation@JsonBackResources(“角色”)和@JsonManagedResources(“角色”),但没有任何变化。我如何解决这个问题?谢谢!

共有3个答案

苏鸿卓
2023-03-14

有时复杂的bean会导致这种问题。正如我所看到的,您与@OneToMany的关系很好,这是正确的原因,如果您在将列表序列化为JSON时使用LAZY,那么依赖关系对象将丢失。毫无疑问,您的问题是一个序列化问题。

你可以试试:

@Entity
@Table(name = "USERS")
//To suppress serializing properties with null values
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
//Ignoring new fields on JSON objects
@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements Serializable {
...

但我建议您使用一种称为数据传输对象(DTO)的良好实践。DTO是在持久bean和表单的中间层使用的bean。最常用于(N)层应用程序中的服务层或控制器,用于在自身和UI层之间传输数据。您可以在服务层中创建DTO,也可以直接在控制器中创建DTO(更好的服务)并将其发送到表单,它还允许您将表单条目直接绑定到控制器中的验证(基本上,您需要在控制器方法的签名中添加参数BindingResult)。DTO允许您创建进行验证的注释,如@NotEmpty、@PasswordsNotEqual、@Size(max=100),这些注释将放在bean中,您还可以将这些注释放在持久性bean中,但不推荐这样做,因为您正在创建一个非常复杂的bean。验证信息以表格形式显示,请参见:

<form:errors id="error-password" path="password" cssClass="help-block"/>

相信我,DTO对您的场景来说非常棒,因为它允许您以正确的方式验证表单条目。

顺致敬意,

南门棋
2023-03-14

调用sendError时,使用IllegalStateException的异常断点暂停执行,然后检查堆栈上的局部变量以获取无法报告的异常,并调用其printStackTrace方法查看其stacktrace。

希望异常的根本原因会很清楚,以及如何解决任何问题。

邵君植
2023-03-14

我建议在导致循环引用的属性上添加@json忽略。这将告诉杰克逊不要序列化该属性。

 类似资料:
  • 在我的应用程序中执行一些操作时,我得到了 Java . lang . illegalstateexception无法调用sendError() 当我再次重新加载页面时,它会正常工作一段时间,但一段时间后它再次显示相同的异常。我如何克服这个异常? 以下是例外: 支柱.xml

  • 我知道这里已经讨论过至少一百万次了,但是每个servlet在调用forward()之前都会重定向或刷新输出。我有同样的问题,但我没有做任何与输出。我的servlet只接受请求参数并提交到数据库,并在请求上设置一个属性。然后,它将请求转发给jsp,jsp显示属性。我在Tomcat7上使用Servlet3.0。下面是我的servlet doPost方法,后面是转发到的jsp: JSP: 我相信我可能错

  • 问题内容: 我正在尝试使用以下代码将值从servlet传递到jsp页面: 当我运行页面时,我得到: 错误: 我尝试使用: 但是我遇到了同样的错误。 如何解决这个错误? 问题答案: 您已经在catch代码块中转发了响应: 因此,您不能再次调用: 因为它已经转发(提交)。 因此,您可以做的是:保留一个字符串以分配需要转发响应的位置。

  • 我试图创建一个api的商店以下属性:StoreId,名称,位置,电话,产品列表(ProductId,对象,价格,股票),产品列表的大小 问题是,当存储区与列表中的项目不一致时,它会以以下方式响应: 但是,如果所有的商店都没有项目,就没有问题,但是如果所有的商店都没有项目,api就没用了。

  • 我使用过滤器来确定请求的页面是否具有有效的会话。 这是我的密码<代码>网络。xml: 过滤器类别: 我有一个登录页面,用于检查用户是否有效。如果用户有效,则将控制转移到此servlet。 这在没有过滤器的情况下可以工作,但是当我将控件转发到“//showuserImages.jsp”时,过滤器会显示一个错误。