JPA, возвращающий вложенный объект после создания - 500 Internal Server Error - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть мой главный объект:

@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 [ "обработчик"])

Ответы [ 2 ]

0 голосов
/ 26 апреля 2019

Лучшая практика - НЕ возвращать объект непосредственно в контроллер (потому что это может вызвать исключение стека из-за потока).Сущность должна преобразовываться в DTO (объект передачи данных) и возвращать DTO.

Если вы все еще хотите использовать сущность, вы должны использовать eager вместо lazy для всех ссылок (включая ссылочный объект внутри ссылочного объекта);

0 голосов
/ 25 апреля 2019

Можете ли вы попробовать это?Добавьте эту аннотацию к SubObj Class

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="SUB_OBJ_ID")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...