[json] org.hibernate.proxy.pojo.javassist.Javassist 클래스에 대한 시리얼 라이저가 없습니까?

내가 일하고 SpringMVC, Hibernate& JSON하지만 난이 오류를 얻고있다.

HTTP Status 500 - Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.SerializationFeature.FAIL_ON_EMPTY_BEANS) ) 

아래 내 법인을 확인하십시오

    @Entity
@Table(name="USERS")
public class User {

    @Id
    @GeneratedValue
    @Column(name="USER_ID")
    private Integer userId;

    @Column(name="USER_FIRST_NAME")
    private String firstName;

    @Column(name="USER_LAST_NAME")
    private String lastName;


    @Column(name="USER_MIDDLE_NAME")
    private String middleName;

    @Column(name="USER_EMAIL_ID")
    private String emailId;

    @Column(name="USER_PHONE_NO")
    private Integer phoneNo;

    @Column(name="USER_PASSWORD")
    private String password;

    @Column(name="USER_CONF_PASSWORD")
    private String  confPassword;

    @Transient
    private String token;

    @Column(name="USER_CREATED_ON")
    private Date createdOn;

    @OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    @Fetch(value = FetchMode.SUBSELECT)
    @JoinTable(name = "USER_ROLES", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "ROLE_ID") })
    private List<ActifioRoles> userRole = new ArrayList<ActifioRoles>();


    @OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,mappedBy="userDetails")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<com.actifio.domain.Address> userAddress = new ArrayList<com.actifio.domain.Address>();

    @OneToOne(cascade=CascadeType.ALL)
    private Tenant tenantDetails;


    public Integer getUserId() {
        return userId;
    }
    public void setUserId(Integer userId) {
        this.userId = userId;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getEmailId() {
        return emailId;
    }
    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getConfPassword() {
        return confPassword;
    }
    public void setConfPassword(String confPassword) {
        this.confPassword = confPassword;
    }
    public Date getCreatedOn() {
        return createdOn;
    }
    public void setCreatedOn(Date createdOn) {
        this.createdOn = createdOn;
    }

    public List<ActifioRoles> getUserRole() {
        return userRole;
    }

    public void setUserRole(List<ActifioRoles> userRole) {
        this.userRole = userRole;
    }
    public String getMiddleName() {
        return middleName;
    }
    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }
    public Integer getPhoneNo() {
        return phoneNo;
    }
    public void setPhoneNo(Integer phoneNo) {
        this.phoneNo = phoneNo;
    }

    public List<com.actifio.domain.Address> getUserAddress() {
        return userAddress;
    }
    public void setUserAddress(List<com.actifio.domain.Address> userAddress) {
        this.userAddress = userAddress;
    }
    public Tenant getTenantDetails() {
        return tenantDetails;
    }
    public void setTenantDetails(Tenant tenantDetails) {
        this.tenantDetails = tenantDetails;
    }
    public String getToken() {
        return token;
    }
    public void setToken(String token) {
        this.token = token;
    }

    }

어떻게 해결할 수 있습니까?



답변

최대 절전 모드 프록시 개체를 통한 지연로드와 비슷한 문제가있었습니다. 지연로드 된 개인 속성이있는 클래스에 다음과 같이 주석을 추가하여 문제를 해결했습니다.

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

JSON 직렬화를 해당 주석에 중단하는 프록시 개체의 속성을 추가 할 수 있다고 가정합니다.

문제는 엔티티가 느리게로드되고 완전히로드되기 전에 직렬화가 발생한다는 것입니다.

Hibernate.initialize(<your getter method>);


답변

이것을 추가하기 위해 동일한 문제가 발생했지만 제공된 답변이 작동하지 않았습니다. 예외의 제안을 받아들이고 application.properties 파일에 추가하여 수정했습니다.

spring.jackson.serialization.fail-on-empty-beans=false

Hibernate 4.3과 함께 Spring Boot v1.3을 사용하고 있습니다.

이제 전체 개체와 중첩 된 개체를 직렬화합니다.

수정 : 2018

여전히 댓글이 있기 때문에 여기서 명확히하겠습니다. 이것은 절대적으로 오류를 숨 깁니다. 성능에 미치는 영향이 있습니다. 그 당시에는 나중에 전달하고 작업 할 무언가가 필요했습니다 (더 이상 봄을 사용하지 않고 수행했습니다). 예, 문제를 정말로 해결하고 싶다면 다른 사람의 말을 들어보세요. 지금 당장 사라지기를 원한다면이 답변을 사용하십시오. 끔찍한 생각이지만, 도대체 효과가있을 수 있습니다. 기록을 위해,이 후 다시 충돌이나 문제가 발생하지 않았습니다. 그러나 그것은 아마도 SQL 성능 악몽이 된 원인 일 것입니다.


답변

이전 답변에서 올바르게 제안했듯이 지연로드는 데이터베이스에서 개체를 가져올 때 중첩 된 개체를 가져 오지 않고 나중에 필요할 때 가져올 수 있음을 의미합니다.

이제 Jackson은 중첩 된 객체를 직렬화하려고 시도하지만 (== JSON을 생성) 일반 객체 대신 JavassistLazyInitializer를 찾으면 실패합니다. 이것은 당신이 보는 오류입니다. 이제 어떻게 해결할까요?

이전에 CP510에서 제안한대로 한 가지 옵션은 다음 구성 줄에서 오류를 억제하는 것입니다.

spring.jackson.serialization.fail-on-empty-beans=false

그러나 이것은 원인이 아니라 증상을 다루는 것입니다 . 우아하게 해결하려면 JSON에서이 객체가 필요한지 여부를 결정해야합니까?

  1. JSON 형식의 개체가 필요한 경우 FetchType.LAZY원인이되는 필드 에서 옵션을 제거합니다 (가져 오는 루트 엔터티뿐 아니라 일부 중첩 개체의 필드 일 수도 있음).

  2. JSON의 객체가 필요하지 않은 경우이 필드의 getter (또는 들어오는 값을 허용 할 필요가없는 경우 필드 자체)에 다음과 같이 주석을 추가합니다 @JsonIgnore.


    // this field will not be serialized to/from JSON
    @JsonIgnore
    private NestedType secret;

더 복잡한 요구 사항 (예 : 동일한 엔티티를 사용하는 다른 REST 컨트롤러에 대한 다른 규칙)이있는 경우 jackson 보기 또는 필터링을 사용 하거나 매우 간단한 사용 사례의 경우 중첩 된 개체를 개별적으로 가져올 수 있습니다.


답변

Hibernate lazy-loading을 처리하는 Jackson 용 애드온 모듈을 사용할 수 있습니다.

https://github.com/FasterXML/jackson-datatype-hibernate에 대한 자세한 정보는 최대 절전 모드 3과 4를 별도로 지원합니다.


답변

문제는 엔티티를 검색하는 방식이라고 생각합니다.

아마도 다음과 같이 할 수 있습니다.

Person p = (Person) session.load(Person.class, new Integer(id));

get대신 방법을 사용해보십시오.load

Person p = (Person) session.get(Person.class, new Integer(id));

문제는로드 방법을 사용하면 실제 객체가 아닌 프록시 만 얻을 수 있다는 것입니다. 프록시 개체에는 속성이 이미로드되어 있지 않으므로 직렬화가 발생하면 직렬화 할 속성이 없습니다. get 메서드를 사용하면 실제로 실제 개체를 얻을 수 있으며이 개체는 실제로 직렬화 될 수 있습니다.


답변

그것은 나를 위해 작동합니다

@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})

예 :

@Entity
@Table(name = "user")
@Data
@NoArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private Date created;

}


답변

문제를 해결하는 방법에는 두 가지가 있습니다.

방법 1 :

추가
spring.jackson.serialization.fail-on-empty-beans=falseapplication.properties

방법 2 :

join fetchJPQL 쿼리에서 사용 하여 상위 개체 데이터를 검색합니다. 아래를 참조하세요.

@Query(value = "select child from Child child join fetch child.parent Parent ",
           countQuery = "select count(*) from Child child join child.parent parent ")
public Page<Parent> findAll(Pageable pageable);