JPA创建后返回嵌套对象-500 Internal Server Error

时间:2019-04-25 13:11:37

标签: java spring hibernate jpa

我有我的主要对象:

@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = MAIN_OBJ)
public class MainObj {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "MAIN_OBJ_ID", unique = true, nullable = false)
    private Integer manObjId;

    @ManyToOne
    @JoinColumn(name = "SUB_OBJ_ID", referencedColumnName = "SUB_OBJ_ID", nullable = false)
    @NotNull
    private SubObj subObj;

}

及其子对象:

@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SUB_OBJ)
public class SubObj {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "SUB_OBJ_ID", unique = true, nullable = false)
    private Integer subObjId;

    @Column(name = "NAME", nullable = false)
    @NotNull
    private String name;

}

创建作品时:

@Override
@Transactional
public MainObj create(MainObj mainObj) {
    MainObj createdMainObj = mainObjRepository.save(mainObj);
    return createdMainObj;
}

它可以正确保存,但是当我将其返回给用户(通过控制器返回)时,我得到了500。调试后,我可以看到subObj中的所有字段均为空。

但是它确实创建了mainObj并将其放入数据库中,只是无法序列化并返回。

如果跟踪得足够多,我会看到:

  

找不到用于类的序列化器   org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer

不太确定我需要添加什么,以便可以将完全创建的对象及其对subObj的外键引用返回给用户。

我尝试过Hibernate.initialize(),就像很多帖子说的那样,但是没有运气。

如果不清楚,它会给我其中之一:

enter image description here

完整堆栈跟踪(已删除一些详细信息):

  

org.springframework.http.converter.HttpMessageNotWritableException:   无法编写JSON:找不到类的序列化程序   org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer,无   发现的用于创建BeanSerializer的属性(为避免出现异常,   禁用SerializationFeature.FAIL_ON_EMPTY_BEANS);嵌套异常为   com.fasterxml.jackson.databind.JsonMappingException:没有序列化程序   发现上课   org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer,无   发现的用于创建BeanSerializer的属性(为避免出现异常,   禁用SerializationFeature.FAIL_ON_EMPTY_BEANS)(通过引用   链:   com.path.to.MainObj [“ subObj”]-com.path.to.SubObj _ $$ _ jvsta14_f [“ handler”])

2 个答案:

答案 0 :(得分:0)

可以请您试试吗? 将此注释添加到SubObj类

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="SUB_OBJ_ID")

答案 1 :(得分:0)

最佳做法是不要直接在控制器中返回实体(因为这可能会导致堆栈溢出异常)。该实体应转换为DTO(数据传输对象)并返回DTO。

如果您仍然想使用实体,则应该对所有引用使用eager而不是lazy(在引用对象内部包括引用对象);