【问题标题】:StackOverflowError occurred when loading data from database从数据库加载数据时发生 StackOverflowError
【发布时间】:2017-05-20 14:40:39
【问题描述】:

我有 java 应用程序,它使用 jpa 框架连接到数据库。 对象UserInformation 包含AdditionData 对象,当我执行userInformationRepository.findByUserId(id) 时收到错误。 作为回应,我看到带有许多内部对象的 json

userInformation->additionData->userInformation->userInformation->additionData->userInformation->....

例外:

>java.lang.StackOverflowError: null
 Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate com.entity.UserInformation.toString()


java.lang.StackOverflowError: null
    at javax.servlet.ServletResponseWrapper.getBufferSize(ServletResponseWrapper.java:167) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
    at javax.servlet.ServletResponseWrapper.getBufferSize(ServletResponseWrapper.java:167) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.springframework.security.web.util.OnCommittedResponseWrapper.checkContentLength(OnCommittedResponseWrapper.java:232) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.util.OnCommittedResponseWrapper.access$200(OnCommittedResponseWrapper.java:33) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:637) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at com.fasterxml.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:2033) ~[jackson-core-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.core.json.UTF8JsonGenerator.writeRaw(UTF8JsonGenerator.java:632) ~[jackson-core-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.core.json.UTF8JsonGenerator.writeRaw(UTF8JsonGenerator.java:555) ~[jackson-core-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.core.json.UTF8JsonGenerator.writeNumber(UTF8JsonGenerator.java:931) ~[jackson-core-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.std.NumberSerializers$FloatSerializer.serialize(NumberSerializers.java:194) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690) ~[jackson-databind-2.8.4.jar:2.8.4]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.8.4.jar:2.8.4]

用户信息实体

@Data
@Entity(name = "user_information")
public class UserInformation {
    @Id
    @Column(name = "uuid")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column(name = "user_id")
    private Long userId;
    @Column(name = "title", length = 64)
    private String title;
    @Column(name = "message", length = 128)
    private String message;
    @OneToOne(mappedBy = "userInformation")
    private AdditionData additionData;
}

AdditionData实体

@Setter @Getter
@Entity(name = "addition_data")
public class AdditionData {
    @Id
    @Column(name = "uuid")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @OneToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "parent_id")
    private UserInformation userInformation;
}

UserInformation 实体的存储库

@Repository
public interface UserInformationRepository extends CrudRepository<UserInformation, Long> {
    List<UserInformation> findByIdIn(List<Long> ids);
    UserInformation findByUserId(Long userId);
}

为什么会出现错误?实体中的关系配置是否有错误?

【问题讨论】:

  • 您是否覆盖了这些实体上的toString() 方法?

标签: java json entity-framework spring-data-jpa


【解决方案1】:

通常将 JSON 序列化为循环链接的问题。就像你的两个实体之间的那个(UserInformation 有一个 AdditionData 有相同的 UserInformation 等)。

添加@JsonIgnore 成员之一以停止循环。为了更好地衡量,我会在您的 lombok @Data 注释中添加一个排除项,以防止在调用 toString() 时出现问题。

当输出生成为 JSON 时,使用 @JsonIgnore 将阻止 Spring 的 Jackson JSON 序列化程序通过引用运行。由于该过程是递归的(成员也被序列化为 json),因此阻止深入这些引用也将阻止 StackOverflowException 被抛出。

【讨论】:

  • 感谢您的回答,我删除了@Data 并添加了@Getter @Setter 注释,但它不能解决问题,但为什么呢?使用@JsonIgnore 可以完美运行。
  • 添加了一些细节,希望能在一定程度上澄清我的答案。
  • 谢谢,你真的帮了我!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多