1

マージで@Id変数が割り当てられないJPA2の特定のケースはありますか?それでも、例外を発生させずにエンティティの新しいインスタンスを返しますか?

私がこの階層を持っているとしましょう:

@MappedSuperclass
abstract class Bar {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  ...
}

@Entity
@Table(name = "BAR_1S")
@Access(AccessType.PROPERTY)
class Bar1 extends Bar {
  ...
}

@Entity
@Table(name = "BAR_2S")
@Access(AccessType.PROPERTY)
class Bar2 extends Bar {
  ...
}

まだ見つかっていない理由により、Bar1のインスタンスはmerge()の後にIDを取得しますが、Bar2のインスタンスは取得しません。少なくともそれはそれがどのように見えるかです。私はさまざまなアプローチを試みてきました。

Hibernate(4.1.4.Final)は、その特定のクラスのインスタンスにIDを割り当てたくないようです。:-)

私が持っている質問:

  • 誰かがこのようなものを持ったことがありますか?

  • 誰かがHibernateのどこにIDが設定されているか教えてもらえますか?したがって、コードのその部分をデバッグして、割り当てをスキップする理由を見つけることができます。IntelliJは、エンティティのフィールドの変更を中断していないようです。

編集-環境構成

  • OS:LMDE amd64
  • データベース:MySQL(5.1.61-2)ConnectJ(5.1.17)
  • JVM:1.7.0_04
  • Hibernate:4.1.4。最終
  • 春:3.1.1

編集-コード

すべてのエンティティクラスは、Barの(間接的な)直接サブクラスです。@Idが定義されている場所は1つだけです。そして、IDを取得するBar2のいくつの同一のケースがあります。しかし、具体的にはBar2はそうではありません。

最終的なBar1bar= new Bar1(); JpaTemplate.merge(bar); <-IDを取得します

最終的なBar2bar= new Bar2(); JpaTemplate.merge(bar); <-IDがありません

アプリケーションはSpringのJpaTemplateを使用してエンティティをマージしています。これは、その特定のクラスを除くすべてのクラスで問題なく実行されます。

したがって、IDを割り当てているHibernateクラスを見つけることができれば、私が見落としていたばかげた詳細を見つけることができるでしょう。:-)

4

2 に答える 2

0

最初の注意:JpaTemplateは非推奨であり、今後は使用しないでください。EntityManagerのmerge()メソッドに委任するだけで、どちらもエンティティを返します。

JPA仕様がマージについて述べていることは次のとおりです。

Xが新しい管理対象エンティティインスタンスの場合、新しい管理対象エンティティインスタンスX'が作成され、Xの状態が新しい管理対象エンティティインスタンスX'にコピーされます。

したがって、IDが生成されると、そのIDは、mergeメソッドに渡すオブジェクトではなく、アタッチされたエンティティに割り当てられます。したがって、mergeメソッドの結果を決して無視しないでください。それ以外の

jpaTemplate.merge(bar);

やったほうがいい:

bar = jpaTemplate.merge(bar);

さらに、JPA仕様には次のようにも記載されています

生成されたIDは、データベースの挿入が行われるまで使用可能であることが保証されていません。

そして、これはおそらくあなたがIDを持っていないもう一つの理由です。MySQLを使用したAUTO戦略であるAFAIKは、データベースの自動インクリメントID列に依存することで構成され、挿入が完了した後にのみIDの値を取得でき、Hibernateはフラッシュが絶対に必要になるまで待機します。挿入を実行します。マージの直後に本当にIDが必要な場合は、次のようにします。

bar = jpaTemplate.merge(bar);
jpaTemplate.flush();
Long id = bar.getId();
于 2012-06-04T17:05:01.117 に答える
0

それを見つけた !マージは、@Transactionalで注釈が付けられたオーバーロードされたメソッドで行われます。オーバーロードメソッドがアノテーションを「継承」すると想定していました。明らかにそうではありません。

オーバーロードメソッドに@Transactionalで注釈を付けることにより、機能しているように見えます。

それはばかげたことだろうと知っていた...

于 2012-06-06T16:45:07.923 に答える