json 找不到类 org.hibernate.proxy.pojo.javassist.Javassist 的序列化程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24994440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:27:17  来源:igfitidea点击:

No serializer found for class org.hibernate.proxy.pojo.javassist.Javassist?

jsonspringhibernate

提问by user2963481

I am working on SpringMVC, Hibernate& JSONbut I am getting this error.

我正在处理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) ) 

Please check my Entity below

请在下面检查我的实体

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

    }

How can I Solve this?

我该如何解决这个问题?

回答by Ankur Singhal

I had a similar problem with lazy loading via the hibernate proxy object. Got around it by annotating the class having lazy loaded private properties with:

我在通过休眠代理对象进行延迟加载时遇到了类似的问题。通过注释具有延迟加载私有属性的类来解决它:

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

I assume you can add the properties on your proxy object that breaks the JSON serialization to that annotation.

我假设您可以在代理对象上添加破坏 JSON 序列化到该注释的属性。

The problem is that entities are loaded lazily and serialization happens before they get loaded fully.

问题是实体被延迟加载,序列化在它们完全加载之前发生。

Hibernate.initialize(<your getter method>);

回答by CP510

Just to add this in, I ran into this same issue, but the supplied answers did not work. I fixed it by taking the exception's suggestion and adding to the application.properties file...

只是为了添加这个,我遇到了同样的问题,但提供的答案不起作用。我通过接受异常的建议并将其添加到 application.properties 文件中来修复它...

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

I'm using Spring Boot v1.3 with Hibernate 4.3

我在 Hibernate 4.3 中使用 Spring Boot v1.3

It now serializes the entire object and nested objects.

它现在序列化整个对象和嵌套对象。

EDIT: 2018

编辑:2018

Since this still gets comments I'll clarify here. This absolutelyonly hides the error. The performance implications are there. At the time, I needed something to deliver and work on it later (which I did via not using spring anymore). So yes, listen to someone else if you really want to solve the issue. If you just want it gone for now go ahead and use this answer. It's a terrible idea, but heck, might work for you. For the record, never had a crash or issue again after this. But it is probably the source of what ended up being a SQL performance nightmare.

由于这仍然得到评论,我将在这里澄清。这绝对只是隐藏了错误。性能影响就在那里。当时,我需要一些东西来交付并稍后处理它(我不再使用 spring 来做到这一点)。所以,是的,如果您真的想解决问题,请听听其他人的意见。如果您只是想让它暂时消失,请继续使用此答案。这是一个糟糕的主意,但哎呀,可能对你有用。作为记录,此后再也没有崩溃或问题。但这可能是导致 SQL 性能噩梦的根源。

回答by MF.OX

As it is correctly suggested in previous answers, lazy loading means that when you fetch your object from the database, the nested objects are not fetched (and may be fetched later when required).

正如之前的答案中正确建议的那样,延迟加载意味着当您从数据库中获取对象时,不会获取嵌套对象(并且可能会在需要时稍后获取)。

Now Hymanson tries to serialize the nested object (== make JSON out of it), but fails as it finds JavassistLazyInitializer instead of normal object. This is the error you see. Now, how to solve it?

现在 Hymanson 尝试序列化嵌套对象(== 从中生成 JSON),但失败了,因为它找到了 JavassistLazyInitializer 而不是普通对象。这是你看到的错误。现在,如何解决?

As suggested by CP510 previously, one option is to suppress the error by this line of configuration:

正如之前 CP510 所建议的,一种选择是通过这一行配置来抑制错误:

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

But this is dealing with the symptoms, not the cause. To solve it elegantly, you need to decide whether you need this object in JSON or not?

但这是处理症状,而不是原因。为了优雅地解决它,您需要决定是否需要JSON中的这个对象?

  1. Should you need the object in JSON, remove the FetchType.LAZYoption from the field that causes it (it might also be a field in some nested object, not only in the root entity you are fetching).

  2. If do not need the object in JSON, annotate the getter of this field (or the field itself, if you do not need to accept incoming values either) with @JsonIgnore, for example:

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

  1. 如果您需要 JSON 中的对象,请FetchType.LAZY从导致它的字段中删除该选项(它也可能是某个嵌套对象中的一个字段,而不仅仅是您正在获取的根实体中的一个字段)。

  2. 如果不需要 JSON 中的对象,请使用 注释此字段(或字段本身,如果您也不需要接受传入值)的 getter @JsonIgnore,例如:

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

Should you have more complex needs (e.g. different rules for different REST controllers using the same entity), you can use Hymanson viewsor filteringor for very simple use case, fetch nested objects separately.

如果您有更复杂的需求(例如,使用同一实体的不同 REST 控制器的不同规则),您可以使用 Hymanson视图过滤,或者对于非常简单的用例,分别获取嵌套对象。

回答by Marco Andreini

You could use the add-on module for Hymanson which handles Hibernate lazy-loading.

您可以使用 Hymanson 的附加模块来处理 Hibernate 延迟加载。

More info on https://github.com/FasterXML/Hymanson-datatype-hibernatewich support hibernate 3 and 4 separately.

有关https://github.com/FasterXML/Hymanson-datatype-hibernate 的更多信息,分别支持 hibernate 3 和 4。

回答by Carlos Zegarra

I think that the problem is the way that you retrieve the entity.

我认为问题在于您检索实体的方式。

Maybe you are doing something like this:

也许你正在做这样的事情:

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

Try using the method getinstead of load

尝试使用该方法get而不是load

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

The problem is that with load method you get just a proxy but not the real object. The proxy object doesn't have the properties already loaded so when the serialization happens there are no properties to be serialized. With the get method you actually get the real object, this object could in fact be serialized.

问题是使用 load 方法你只能得到一个代理而不是真正的对象。代理对象没有已经加载的属性,所以当序列化发生时,没有要序列化的属性。使用 get 方法您实际上可以获得真实的对象,这个对象实际上可以被序列化。

回答by GiraffeTree

it works for me

这个对我有用

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

e.g.

例如

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

}

回答by fangting

There are two ways to fix the problem.

有两种方法可以解决问题。

Way 1:

方式一

Add spring.Hymanson.serialization.fail-on-empty-beans=falseinto application.properties

添加 spring.Hymanson.serialization.fail-on-empty-beans=falseapplication.properties

Way 2:

方式2

Use join fetchin JPQL query to retrieve parent object data, see below:

join fetch在 JPQL 查询中使用以检索父对象数据,见下文:

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

回答by Akitha_MJ

Add this Annotation to Entity Class (Model) that works for me this cause lazy loading via the hibernate proxy object.

将此注释添加到对我有用的实体类(模型),这会导致通过休眠代理对象延迟加载。

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

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

回答by Sai Goud

This Exception

此异常

org.springframework.http.converter.HttpMessageNotWritableException

org.springframework.http.converter.HttpMessageNotWritableException

getting because, I hope so, your are sending response output as Serializable object.
This is problem occurring in spring. To over come this issue, send POJO object as response output.

因为,我希望如此,您将响应输出作为 Serializable 对象发送。
这是春天发生的问题。为了解决这个问题,发送 POJO 对象作为响应输出。

Example :

例子 :

    @Entity
    @Table(name="user_details")
    public class User implements Serializable{

        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        @Column(name="id")
        private Integer id;

        @Column(name="user_name")
        private String userName;

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

        @Column(name="phone_no")
        private String phone;

//setter and getters

POJO class:

POJO类:

public class UserVO {

    private int Id;
    private String userName;
    private String emailId;
    private String phone;
    private Integer active;

//setter and getters

In controller convert the serilizable object fields to POJO class fields and return pojo class as output.

在控制器中将可序列化对象字段转换为 POJO 类字段并返回 pojo 类作为输出。

         User u= userService.getdetials(); // get data from database

        UserVO userVo= new UserVO();  // created pojo class object

        userVo.setId(u.getId());
        userVo.setEmailId(u.getEmailId());
        userVo.setActive(u.getActive());
        userVo.setPhone(u.getPhone());
        userVo.setUserName(u.getUserName());
       retunr userVo;  //finally send pojo object as output.

回答by GMsoF

In the Hibernate 5.2 and above, you able to remove the hibernate proxy as below, it will give you the actual object so you can serialize it properly:

在 Hibernate 5.2 及更高版本中,您可以删除 hibernate 代理,如下所示,它将为您提供实际对象,以便您可以正确地序列化它:

Object unproxiedEntity = Hibernate.unproxy( proxy );