boden
boden

Reputation: 1681

StackOverflowError occurred when loading data from database

i have java application with connetion to database with jpa framework. Object UserInformation contains AdditionData object, when I do userInformationRepository.findByUserId(id) receive error. In response I see json with many inner objects

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

Exception:

>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 entity

@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 entity

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

Repository for UserInformation entity

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

Why error occurred? Do I have error in configuration for relations in entity?

Upvotes: 0

Views: 2104

Answers (1)

CollinD
CollinD

Reputation: 7573

Generally jackson JSON serialization into problems with cyclical links. Like the one between your two entities (UserInformation has an AdditionData which has the same UserInformation etc).

Add @JsonIgnore one of the members to stop the cycle. For good measure I would add an exclude to your lombok @Data annotation to prevent the issue when toString() is called.

Using @JsonIgnore will prevent spring's Jackson JSON serializer from running through the references when output is generated as JSON. Since that process is recursive (members are serialized to json as well), preventing diving into those references will also prevent the StackOverflowException from being thrown.

Upvotes: 5

Related Questions