これは、フォローアップコードを含むrzymekの回答からの私のコメントです。
クエリが呼び出されるたびにEntityManagerがフラッシュされるように聞こえたため、OPが抱えていた問題を再現しようとしました。しかし、そうではありません。@PostUpdateメソッドは、私が知る限り、データベースに実際に変更が加えられた場合にのみ呼び出されます。DBにまだフラッシュされていないEntityManagerで変更を加えた場合、query.getResultListは、DBへのフラッシュをトリガーします。これは、予想される動作です。
Place valinorDb = em.find(Place.class, valinorId);
// this should not trigger an PostUpdate and doesn't
// TODO: unit-testify this
em.merge(valinorDb);
valinorDb.setName("Valinor123");
valinorDb.setName("Valinor");
// this shouldn't trigger an PostUpdate because the Data is the same as in the beginning and doesn't
em.merge(valinorDb);
{
// this is done to test the behaviour of PostUpdate because of
// this:
// http://stackoverflow.com/questions/12097485/why-does-a-jpa-preupdate-annotated-method-get-called-during-a-query
//
// this was tested by hand, but should maybe changed into a unit
// test? PostUpdate will only get called when there is an actual
// change present (at least for Hibernate & EclipseLink) so we
// should be fine
// to use PostUpdate for automatically updating our index
// this doesn't trigger a flush as well as the merge didn't even trigger one
Place place = (Place) em.createQuery("SELECT a FROM Place a")
.getResultList().get(0);
Sorcerer newSorcerer = new Sorcerer();
newSorcerer.setName("Odalbort the Unknown");
place.getSorcerers().add(newSorcerer);
//this WILL trigger an PostUpdate as the underlying data actually has changed.
place = (Place) em.createQuery("SELECT a FROM Place a")
.getResultList().get(0);
}