Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate和Jackson(java.lang.IllegalStateException:提交响应后无法调用sendError())_Java_Json_Hibernate_Orm_Jackson - Fatal编程技术网

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

Hibernate和Jackson(java.lang.IllegalStateException:提交响应后无法调用sendError()),java,json,hibernate,orm,jackson,Java,Json,Hibernate,Orm,Jackson,你好,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 c

你好,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;
还有一个控制器,通过Jackson从用户Json生成。用方法

  @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

当我添加@OneToMany(mappedBy=“user”,cascade=CascadeType.ALL,fetch=FetchType.EAGER)时,这个问题就出现了,以前它只是fetch=FetchType.EAGER,但我无法用他的角色保存用户,在这种情况下,表user\u角色是空的。在Jackson的某个地方,我在无限循环中找到了一些解决方案,添加了一些anotation@JsonBackReference(“角色”)和@JsonManagedReference(“角色”),但没有任何改变。我怎样才能解决这个问题?谢谢大家!

我建议在导致循环引用的属性上添加
@jsonignore
。这将告诉jackson不要序列化该属性。

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


希望异常的根本原因届时会很清楚,并知道如何解决问题。

有时复杂的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)的良好实践。DTOS是豆在中间层的持久豆和形式。最常用于(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对您的场景来说非常棒,因为它允许您以正确的方式验证表单条目


最好的问候

我发现最好的解决方案是不直接返回实体。 在您的情况下,您直接在登录控制器中返回“用户”实体。相反,只需返回user.id或user.firstname,等等。这样就可以了。当我们返回任何实体时,编译器进入无限递归循环

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