2017-08-17 3 views
1

私は現在、エンドポイントがデータベースに格納された特定のオブジェクトのPageを返すスプリングブートアプリケーションを実行しています。私たちの目的のために、そのオブジェクトを "x"と呼ぶことができます。 「x」の中には、遅れて取得されるように設定されたオブジェクトのリストがあります。jsonオブジェクトがjsonオブジェクトをシリアル化するときに、hibernate5が遅延フェッチを起こさないようにするにはどうすればいいですか?

@Entity 
@DynamicUpdate 
class x { 

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

     @JsonIgnore 
     @OneToMany(mappedBy = "x", cascade = CascadeType.MERGE, fetch = FetchType.LAZY) 
     private List<y> lazilyFetchedList; 

     @Override 
     public Integer getId() { 
      return id; 
     } 

     public void setId(Integer id) { 
      this.id = id; 
     } 

     @JsonIgnore 
     public List<y> getLazilyFetchedList() { 
      return lazilyFetchedList; 
     } 

     public void setLazilyFetchedList(List<y> lazilyFetchedList) { 
      this.lazilyFetchedList = lazilyFetchedList; 
     } 
} 

私はlazilyFetchedListがGETコール時にクライアントに送信されるようにしたくないので、私は上記の@JsonIgnoreを設定します。

マイ問題は、フィールドが正常にJSONレスポンスを表示するクライアントとしてジャクソンによって無視されるにもかかわらず、です。しかし、Javaのオブジェクト "x"をシリアル化するときには、によってlazilyFetchedListをフェッチするために、休止状態によってさらにクエリーが作成されます(jacksonが結果を使用していなくても)。

私は既にAvoid Jackson serialization on non fetched lazy objectsから回答を試みましたが、答えがどれもうまくいかないようです。

@Configuration 
@EnableWebMvc 
public class ApiWebConfig extends WebMvcConfigurerAdapter { 

@Bean 
public ObjectMapper objectMapper() { 
    ObjectMapper objectMapper = new ObjectMapper(); 
    configureDefaultObjectMapper(objectMapper); 
    customizeObjectMapper(objectMapper); 
    return objectMapper; 
} 

public static void configureDefaultObjectMapper(ObjectMapper objectMapper) { 
    objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); 
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); 
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); 
    objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); 

    objectMapper.registerModule(new Hibernate5Module()); 

    JavaTimeModule javaTimeModule = new JavaTimeModule(); 
    javaTimeModule.addSerializer(ZonedDateTime.class, ZonedDateTimeSerializer.INSTANCE); 
    javaTimeModule.addSerializer(OffsetDateTime.class, OffsetDateTimeSerializer.INSTANCE); 
    objectMapper.registerModule(javaTimeModule); 
} 

/** 
* Only register a json message converter 
*/ 
@Override 
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
    converters.clear(); 

    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 
    converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON)); 
    converter.setObjectMapper(objectMapper()); 

    converters.add(converter); 
} 
} 

バージョン:

  • 春ブーツ1.5

    @RequestMapping(value = "/{id}/x", method = RequestMethod.GET) 
        public ApiResponse<?> findX(@PathVariable Integer id, PagingInfo info) { 
         Page<x> page = repo.findX(id, toPageable(info)); 
         return toResponse(page, FIND_LIST_STATUS); 
        } 
    

    ここでは、オブジェクトマッパーの私の設定は次のようになります。ここでは

    は私のコントローラがどのように見えるかです。 3

  • ジャクソン2.8.6
  • 休止5.0.11.Final
  • ジャクソン・データ型-hibernate5 2.9.0
+0

ゲッター/セッターを取り外すとどうなりますか? –

+2

エンティティクラスを使用せず、jsonに対してpojoを作成します。 – surya

+0

問題は、プロジェクト内に多くのエンティティがあります。だから、それぞれのpojoを作成することは実現可能な解決策ではありません。さらに、2つの異なる場所でフィールドの変更を必要とするソリューションを実装したくないのです。誰かがそのエンティティを更新するとコードが壊れる可能性が高いからです。私は、図書館自体によって扱われる、より一般的な解決策を希望します。 –

答えて

0

は、あなたのpom.xmlに以下の依存関係を追加します。

<dependency> 
    <groupId>com.fasterxml.jackson.datatype</groupId> 
    <artifactId>jackson-datatype-hibernate5</artifactId> 
</dependency> 

(そうでない場合は、バージョンを追加します春ブート依存性や、ばねブートスタータ親によって管理される) は、あなたの春の設定クラスに次のコードを追加します

@Bean 
protected Module module() { 
    return new Hibernate5Module(); 
} 

以下の輸入品:

import com.fasterxml.jackson.databind.Module; 
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; 
関連する問題