从数据库加载数据时发生StackOverflowError

时间:2017-01-05 21:58:36

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

我有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]

UserInformation 实体

@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);
}

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

1 个答案:

答案 0 :(得分:4)

一般杰克逊JSON序列化成循环链接问题。就像您的两个实体之间的那个(words有一个UserInformation具有相同的AdditionData等。

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

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