2017-09-19 7 views
1

私のコードには、PlaceクラスとAddressクラスがあります。住所1:N場所。@EmbeddedIdクラス内の@ContainedIn

インデックスが1つあります。住所インデックスです。

アドレスが保存されると、問題なく動作します。しかし、プレイスが保存されると、アドレスのインデックスは更新されません。

問題は多分バグです: @ContainedInが@EmbeddedIdクラスの中のフィールドにある場合、それは動作しません。 internメカニズムは通知されないため、インデックスは変更されません。

は、私はいくつかの回避策を試してみた:

  • 更新されたインデックスを手動でfullTextSession.index(obj)。 - > DO NOT WORK
  • PlaceIDからのマップされたアドレス。挿入可能であり、更新可能なものはfalseです。私はHibernateのPreInsertEventListener/PreUpdateEventListenerの中でこの問題を解決しようとするために、HSearchのinternメカニズムを研究しようとしました。 - >失敗しました。

私はこの作業を何らかの方法で行う必要があります。次に、私の主な質問は...どうすれば動作させることができますか?

例:Hibernate Searchのインターンメカニズム/クラスがありますか?私は(手動の方法)PreInsertEventListener/PreUpdateEventListenerの内部で使用することができているか、そのようなsomethink ...置きクラスの

コード:

@Entity 
public class Place { 

    @IndexedEmbedded 
    @EmbeddedId 
    private PlaceID id; 

    @ContainedIn 
    @ManyToOne 
    @JoinColumns({ 
     @JoinColumn(name = "address_id", insertable = false, updatable = false, referencedColumnName = "id"), 
     @JoinColumn(name = "address_secondId", insertable = false, updatable = false, referencedColumnName = "secondId") 
    }) 
    private Address address; 

    @Field(store = Store.YES) 
    private String name; 
} 

Addressクラスのコード:

@Indexed 
@Entity 
public class Address { 

    @FieldBridge(impl = AddressIdFieldBridge.class) 
    @IndexedEmbedded 
    @EmbeddedId 
    private AddressID id; 

    @Field(store = Store.YES) 
    private String street; 

    @Field(store = Store.YES) 
    private String city; 

    @IndexedEmbedded 
    @OneToMany(mappedBy = "id.address") 
    private Set<Place> places; 
} 

バージョン依存関係:

<hibernate.version>5.2.11.Final</hibernate.version> 
<hibernate-search.version>5.8.0.Final</hibernate-search.version> 
<lucene.version>5.5.4</lucene.version> 

エンティティおよびインデックスを更新するコード:

@Test 
public void givenPlaces_updateAddressIndex(Address address) { 
    List<Place> places = new ArrayList<>(); 

    for (int i = 0; i < 10; i++) { 
     Place place = new Place(new PlaceID((long) new Random().nextInt(500), address)); 
     place.setName("Place " + new Random().nextInt(500)); 
     places.add(place); 
    } 

    placeRepository.save(places); 
} 

結果:

enter image description here

答えて

2

更新されたインデックスを手動fullTextSession.index(OBJ)。 - >が動作しない、とあなたは「アドレス」オブジェクトを渡していることを場合

が、それは@IndexedEmbedded/@ContainedInに関連していない動作しません。

このコードAddressplacesフィールドを更新しません:エンティティとインデックスを更新するためのコードが

。 Hibernate SearchはAddressを再インデックスするかもしれませんが、現在Hibernateセッションにあるアドレスは空のplacesフィールドを持っているので、よく...

コード内に新しい場所をAddress.placesに追加しようとすると、機能するはずです。

+0

ありがとう、Yoann!まあ、私はエンティティを "場所クラス"の側で保存し、 "住所クラス"の側で保存する必要はありません。私のチームが常に「住所側」で場所を更新することを保証できないためです。 "場所"クラスの側で "アドレスインデックス"を更新する方法はありますか? (Obs:私のシナリオは、他のクラスとは別のものですが、私は同じ状況でHsearchのdocの例を使って簡単なプロジェクトを作っています) – adyjr

+0

@adyjrいいえ、私は自動的に関連の非所有側。ただし、双方向の関連付けをしている場合は、両サイドを最新の状態に保つ必要があります。または、Hibernate Searchだけでなくビジネスコードでも問題が発生します。 –

+0

Yoannは正しいです。常にHibernateや他のJPA実装を使用して、関係の両側を常に一貫して更新するのが一般的な要件です。 Hibernateを使うと、これを自動的に行うことができますが、エンティティ拡張を有効にしてコンパイルされたクラスに必要なコードを挿入できるようにする必要があります。 – Sanne

関連する問題