JPA(Hibernate)エージェントクラスのhibernateLazyInitializer属性系列化異常

3747 ワード

今日Spring BootプロジェクトでJPA(Hibernate)を使用してデータベースにアクセスしたとき、
spring:
  jpa:
    generate-ddl: false
    show-sql: true
    hibernate:
      ddl-auto: none
    open-in-view: true

エンティティ・オブジェクトのクエリー中に例外が発生しました:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.xgclassroom.model.User$HibernateProxy$PpGM4JxY["hibernateLazyInitializer"])

次のエラーメッセージをよく見ると、jacksonがhibernateの永続化エンティティクラスのエージェントオブジェクトをシーケンス化する際に、エージェントクラスの「hibernateLazyInitializer」属性が空になり、シリーズ化計画SerializationFeatureがトリガーされたことが直接の原因である.FAIL_ON_EMPTY_BEANSは、「空のBeanが発生したときにシーケンス化に失敗した」ということです.
「hibernateLazyInitializer」プロパティが空の場合、遅延ロード(open-in-view:true)を無効にし、falseに設定するとno Sessionエラーが発生します.
エラーメッセージではjacksonのSerializationFeatureを無効にすることができます.FAIL_ON_EMPTY_BEANSという一連化ルールは、この異常(異常情報の赤文字で示す)を回避するものであり、以下のようにSerializationFeatureを無効にすることができる.FAIL_ON_EMPTY_BEANSルールの新しいObjectMapperは、デフォルトのObjectMapperのメソッドを置き換えて目的を達成します.
@SpringBootApplication
@Configuration
public class ProviderUserApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderUserApplication.class, args);
    }

    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    }
}

  
もちろん、空の属性の系列化は、対応するエンティティクラスで@JsonIgnorePropertiesで直接無視することもできます.
@Getter
@Setter
@Entity
@JsonIgnoreProperties(value = {"hibernateLazyInitializer"})
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String username;

    @Column
    private String name;

    @Column
    private Integer age;

    @Column
    private BigDecimal balance;
}

 
次に、2つの方法で再現されたシリーズ化結果の例を見てみましょう.
{"id":1,"username":"account1","name":"  ","age":20,"balance":100.00,"hibernateLazyInitializer":{}}
{"id":1,"username":"account1","name":"  ","age":20,"balance":100.00}