2016-08-16 10 views
2

私はHibernate 5.1.0.Finalを使用します。マイGenericDAOクラスの主な方法:Hibernateは完全にエンティティの子をリフレッシュしません

public T save(T entity) { 
    entityManager.getTransaction().begin(); 
    entityManager.persist(entity); 
    entityManager.getTransaction().commit(); 
} 

public T find(Long entityId) { 
    T e = (T) entityManager.find(type, entityId); 
    entityManager.refresh(e); 
    return e; 
} 

私はList<Image> imagesが含まれているItem実体を持っています。

@Entity 
@Table(name="item") 
public class Item extends GenericEntity { 

    @Column(name="title") 
    String title; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "item", cascade = {CascadeType.ALL}, orphanRemoval = true) 
    @NotFound(action = NotFoundAction.IGNORE) 
    List<Image> images; 

    @Version 
    @Temporal(TemporalType.TIMESTAMP) 
    @Column(name="version") 
    Date version; 

} 


@Entity 
@Table(name="image") 
public class Image extends GenericEntity { 

    @ManyToOne 
    @JoinColumn(name="item") 
    Item item; 

    @Column(name="image_name") 
    String imageName; 

} 

まず、私はgenericDAO.find(id)方法でItemをロードする - それは、画像の最新のリストが含まれています。次に、別のRESTメソッドで同じIDを持つItemをロードし、古いイメージを削除し、新しいイメージを追加してタイトルを変更します。後でItemgenericDAO.find(id)に最初のRESTメソッドでリロードしようとすると、古い画像が表示されます。Itemのタイトルが正しく取得されている間に再び選択されません。

完全に更新されたエンティティをデータベースから取得するにはどうすればいいですか?

+0

'images'フィールドを更新してもよろしいですか? – davidxxx

+0

はい、DBから直接クエリを実行すると変更が表示されます。 – Justas

+0

あなたはどこかでキャッシュを使用します。 Hibernateでレベル2キャッシュを使用しますか?または、アプリケーションのキャッシュメカニズム – davidxxx

答えて

1

entityManagersのキャッシングの方法は、requestのスコープでは正しいが、目に見えるように副作用があります。
Hibernateのレベル1キャッシュを使用します。
トランザクションで別のentityManagerインスタンスを使用しないのはなぜですか?
ユーザ要求ごとにEntityManagerをインスタンス化するのは高価ではありません。

エンティティマネージャをキャッシュする場合は、レベル1のキャッシュをクリアしていないようであるため、entityManager.refres‌​h(e)は十分ではないようです。したがって、最初のレベルのキャッシュをクリアする場合は、persistenceContextをクリアしてください。保証はありませんが、試すことができます。entityManager.clear()

個人的には、トランザクションでユニークなentityManagerインスタンスを使用するソリューションが個人的には好きです。安くてクリアなデザインです。

+0

entityManager.clear(); DAOにそれを注入する前に問題を解決する。 – Justas

+0

フィードバックありがとう:) – davidxxx

関連する問題