【问题标题】:No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor没有为类 org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor 找到序列化程序
【发布时间】:2019-03-10 10:10:45
【问题描述】:

当我尝试导航到端点时,我收到以下错误

类型定义错误:[简单类型,类org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor];嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor 并且没有发现创建 BeanSerializer 的属性(为避免异常,请禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS)

我检查了所有模型,所有属性都有 getter 和 setter。那么有什么问题呢?

我可以通过添加 spring.jackson.serialization.fail-on-empty-beans=false 来解决这个问题,但我认为这只是隐藏异常的一种解决方法。

编辑

Product模特:

@Entity
public class Product {
    private int id;
    private String name;
    private String photo;
    private double price;
    private int quantity;
    private Double rating;
    private Provider provider;
    private String description;
    private List<Category> categories = new ArrayList<>();
    private List<Photo> photos = new ArrayList<>();
    
    // Getters & Setters
}

PagedResponse 类:

public class PagedResponse<T> {

    private List<T> content;
    private int page;
    private int size;
    private long totalElements;
    private int totalPages;
    private boolean last;
    
    // Getters & Setters
}

RestResponse 类:

public class RestResponse<T> {
    private String status;
    private int code;
    private String message;
    private T result;

    // Getters & Setters
}

在我的控制器中,我正在返回 ResponseEntity&lt;RestResponse&lt;PagedResponse&lt;Product&gt;&gt;&gt;

【问题讨论】:

  • 我遇到了同样的问题,添加了道具条目,我可以看到响应,之前它失败了。感谢这个问题和提示fail-on-empty-beans

标签: java spring hibernate spring-mvc spring-boot


【解决方案1】:

我在使用 spring 存储库做教程时遇到了这个错误。原来是在为我的实体构建服务类的阶段出错。

在你的 serviceImpl 类中,你可能有类似的东西:

    @Override
    public YourEntityClass findYourEntityClassById(Long id) {
      return YourEntityClassRepositorie.getOne(id);
    }

将其更改为:

    @Override
    public YourEntityClass findYourEntityClassById(Long id) {
      return YourEntityClassRepositorie.findById(id).get();
    }

基本上 getOne 是一个延迟加载操作。因此,您只能获得对该实体的引用(代理)。这意味着实际上没有进行数据库访问。只有当您调用它的属性时,它才会查询数据库。 findByID 在您调用它时会“急切地”/立即进行调用,因此您已经完全填充了实际实体。

看看这个:Link to the difference between getOne & findByID

【讨论】:

  • 感谢分享。
  • @Szelek 感谢这一点,我得到了同样的错误,因为我使用 getOne() 方法现在将其更改为 findById(id).get()。
  • 哇,@Szelek,你是上帝。我不明白为什么这个小小的改变救了我的命。
  • 已为我修复,感谢您提供的信息。看过他们使用 getOne() 的教程,有人知道为什么该方法不能正常工作吗?
  • @LayLeangsros 我自己也想知道同样的事情。发现这篇很棒的文章描述了 getOne 和 findById 之间的区别。基本上 getOne 是一个延迟加载操作。因此,您只能获得对该实体的引用(代理)。这意味着实际上没有进行数据库访问。只有当您调用它的属性时,它才会查询数据库。 findByID 在您调用它时会立即进行调用,因此您已经完全填充了实际实体。 javacodemonk.com/…
【解决方案2】:

您可以通过忽略来生成属性的 JSON 输出

@JsonIgnore 

或者如果你有任何延迟加载的属性有关系。您可以在属性顶部使用此注解。

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

例子:

@Entity
public class Product implements Serializable{
   private int id;
   private String name;
   private String photo;
   private double price;
   private int quantity;
   private Double rating;
   private Provider provider;
   private String description;

   @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
   private List<Category> categories = new ArrayList<>();

   @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
   private List<Photo> photos = new ArrayList<>();

   // Getters & Setters
}

如果您仍然有这个错误,请在您的 application.properties 文件中添加这行代码

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

希望您的问题能够得到解决。谢谢。

【讨论】:

  • “@JsonIgnoreProperties”提供的解决方案对我不起作用。从 FetchType.LAZY 更改为 FetchType.EAGER 解决了这个问题。
  • @Subarata Talukder - 如果我们使用@JsonIgnore,那么我们也会丢失实体图的细节......
  • @ghjansen - 我也遇到了同样的错误,但就我而言,我不能继续这样做FetchType.EAGER。你能帮我解决这个问题吗?
  • 我想知道为什么有人会再使用 Serializable 接口。这是 Hibernate 的要求吗?
  • @PAA 抱歉耽搁了。不确定是否仍然及时,但我建议您查看baeldung.com/hibernate-lazy-eager-loading 以仔细检查您是否以正确的方式使用延迟加载。正如“5. 差异”中所解释的,我猜在我的情况下,由于缺少 getter 调用而发生异常,这会触发获取,初始化给定对象的所有属性。除此之外,还有一种使用代理的方法,在同一篇文章中也有解释。我很快就会离开渴望并回到懒惰,因为渴望是一种不好的做法。
【解决方案3】:

将 FetchType 从惰性更改为渴望对我有用。

【讨论】:

    【解决方案4】:

    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 非常适合我。 不会遗漏任何参考对象并解决问题。

    就我而言:

    @Entity
    @Table(name = "applications")
    public class Application implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @NotBlank
        @Size(max = 36, min = 36)
        private String guid;
    
        @NotBlank
        @Size(max = 60)
        private String name;
    
        @Column(name = "refresh_delay")
        private int refreshDelay;
    
        @ManyToOne(fetch = LAZY)
        @JoinColumn(name = "id_production", referencedColumnName = "id")
        @JsonIgnoreProperties(value = {"applications", "hibernateLazyInitializer"})
        private Production production;
    

    【讨论】:

      【解决方案5】:

      这解决了我的问题。

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

      【讨论】:

        【解决方案6】:

        我也面临同样的问题。 我正在使用 repo.getOne(id); 我将其更改为 repo.findById(id)。它返回了可选的,但现在错误消失了

        【讨论】:

          【解决方案7】:

          我也遇到过这个问题。 @Szelek 的回答帮助了我。但我用另一种方式做到了。将 getOne() 方法更改为:

          repository.findById(id).orElse(null)
          

          确保您注意NullPointerException,它会在找不到时生成。

          【讨论】:

          • 这将引发 NullPointer 异常。可选不能返回 null
          • 谢谢。你拯救了我的一天。
          • @jfzr 关于可选:一个容器对象,可能包含也可能不包含非空值。
          【解决方案8】:

          嗯,您是否打算将实体从一个 jvm 实例发送到另一个需要序列化它们的实例?如果是这种情况,我认为错误是因为您以某种方式获取了实体并且 hibernate 正在使用其不可序列化的类,您需要将实体转换为 pojo(我的意思是使用本机类型或可序列化的对象)。

          【讨论】:

          • 我不明白你在说什么,但我想我正在这样做,请检查我的编辑。
          【解决方案9】:

          对我来说,我收到了 DTO 对象的此错误。问题是我没有为 DTO 属性提供吸气剂。因此,Jackson 无法获取这些值并假定 bean 为空。 解决方案

          将 Getter 添加到您的 DTO

          【讨论】:

            【解决方案10】:

            改变

            MyEntityClassRepositorie.getOne(id)
            

            MyEntityClassRepositorie.findById(id).get()
            

            对我来说很好。

            【讨论】:

              猜你喜欢
              • 2019-12-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-09-19
              • 1970-01-01
              • 1970-01-01
              • 2014-02-17
              • 1970-01-01
              相关资源
              最近更新 更多