JPA(Hibernate)エージェントクラスのhibernateLazyInitializer属性系列化異常
3747 ワード
今日Spring BootプロジェクトでJPA(Hibernate)を使用してデータベースにアクセスしたとき、
エンティティ・オブジェクトのクエリー中に例外が発生しました:
次のエラーメッセージをよく見ると、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のメソッドを置き換えて目的を達成します.
もちろん、空の属性の系列化は、対応するエンティティクラスで@JsonIgnorePropertiesで直接無視することもできます.
次に、2つの方法で再現されたシリーズ化結果の例を見てみましょう.
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}