OpenJPA は、エンティティーをデタッチ (およびおそらくシリアライズ) してからマージし直すときに、特定の仮定を行います。
通常、この種の問題が発生するのはシリアライゼーションです。エンティティがシリアライズされると、OpenJPA はロードされたフィールドを追跡する StateManager を失います。その結果、null 値を使用してエンティティーを再びマージすると、OpenJPA はフィールドがロードされたことを確信できず、変更されていないと見なします。
これを修正するには、いくつかのオプションがあります。
シリアライズ可能な StateManager を使用するように OpenJPA を構成できます。これにより、ロードしたフィールドが追跡されます。これを行うには、次のプロパティを persistence.xml に追加します。
<property name="openjpa.DetachState" value="loaded(DetachedStateField=true)"/>
または、エンティティーがデタッチされる前に一連のフィールドをロードするように OpenJPA に指示します。その後、OpenJPA はどのフィールドが存在していたかを認識し、null 値を適切に処理します。オプションは、fetch-groups (OpenJPA の概念ですが、デフォルトではすべての非 LAZY フィールドをロードします)、またはすべてのフィールド (これは高価になる可能性があります) をロードすることです。
ほとんどの場合、fetch-groups をお勧めします。persistence.xml のプロパティは次のとおりです。
<property name="openjpa.DetachState" value="fetch-groups"/>
気が向いたら、デタッチド オブジェクト グラフを使って巧妙なことを行うことができます。OpenJPA マニュアルの詳細については、http://openjpa.apache.org/builds/1.2.2/apache-openjpa-1.2.2/docs/manual/manual.html#ref_guide_detach_graphを参照してください。