0

アプリケーションを Hibernate から OpenJPA に移行しようとすると、"突然" @OneToMany 関係がフェッチされなくなりました。

状況は次のように要約できます: 私は 2 つのエンティティMemberUsernameを持っています。メンバーは複数のユーザー名を持つことができます。Ii は、ユーザー名テーブルに外部キー列として member_id が含まれる 2 つのテーブル (Member と Username) によってデータベースで実現されます。

これにより、次のエンティティが得られます。

@Table(name="member")
public class Member implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Column(unique=true, nullable=false)
private int id;
    ...
    @OneToMany(mappedBy="member")
private List<Username> usernames;
    ...
}

@Entity
@Table(name="username")
public class Username implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Column(insertable=false, updatable=false, unique=true, nullable=false)
private int id;

    //bi-directional many-to-one association to Member
    @ManyToOne
@JoinColumn(name="member_id", nullable=false)
private Member member;
    ...

どちらのエンティティ クラスにも、属性のパブリック セッターとゲッター、および既定のコンストラクターがあります。(「プラグアンドプレイ」アプローチを試し、既存の DB から Eclipse で自動的にクラスを作成しました)。

クラスはpersistence.xmlファイルで宣言されています

<persistence-unit name="...">
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <class>allwi.data.jpa.Member</class>
    <class>allwi.data.jpa.Username</class>

VAADIN フレームワークの JPAContainer を使用してデータをロードしています。休止状態でメンバーデータをロードし、ユーザー名を暗黙的にロードするとうまくいきました。OpenJPA に切り替えた後、usernames コレクションは null です。メンバー オブジェクトでgetUsernames()を呼び出すと、まだ null が返され、追加のフェッチは実行されません。ログ レベルを TRACE に上げたところ、Member テーブルへの単純な SQL フェッチのみが実行されていることがわかります。

また、 Fetch=EAGERCascade=ALLを追加しようとしましたが、違いはありませんでした。

この問題を経験したのは私だけのように見えるので、ばかげた間違いを犯さなければなりません。前述のように、私は VAADIN JPAContainer を使用しています。つまり、基本的に、エンティティ マネージャーの作成にはあまり影響を与えていません。

私は何が欠けていますか?

どうもありがとう

編集1

コード フラグメントを改善し、DB 設計の説明を追加しました。

編集2

動作がJPAContainerに関連しているかどうかを確認しました。したがって、EntityManager を手動で作成しました。

    EntityManagerFactory emf = Persistence.createEntityManagerFactory(...);
    EntityManager em = emf.createEntityManager();       
    Member m = em.find(Member.class, 14661667);

結果は同じです。Member テーブルの列からデータを取得し、Member の @ManyToOne 関係からもデータを取得しますが、@OneToMany 関係コレクションからは取得しません。

編集3

データベースには PostgreSQL を使用しています。

4

3 に答える 3

0

わかりました-この問題は強化戦略に関連していると直感しています。私は Eclipse プラグインのビルド時の拡張機能を使用し、上記の問題に遭遇しました (そして、クラスが「2」ではなく 1.x に拡張されたという警告が表示されました)。

Eclipse ビルドに ant ビルダーを追加しようとしましたが、ビルドが成功した後でも、割り当てられたランタイムでアプリを起動すると、機能強化が実行されていないというメッセージが表示されて失敗しました。

ランタイム拡張は推奨されていないので、これは飛ばしてしまいましたが、代わりに EclipseLink を試してみました...そして!? Woohoo - 実装に変更を加えることなく、再び機能します。

結論:「Apache」と呼ばれるもののすべてが優れていて信頼できるわけではありません。当面は、OpenJPA を避けることを強くお勧めします。

于 2013-05-10T02:04:39.687 に答える
0

注釈のmappedBy要素から判断すると、この関係を双方向の関係としてマッピングしているように見えます。エンティティに注釈@OneToManyを追加する必要があります。@ManyToOneUsername

@Entity
@Table(name="username")
public class Username implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(insertable=false, updatable=false, unique=true, nullable=false)
    private int id;

    @ManyToOne
    @JoinColumn(name="id") //this depends on your column name
    private Member member;

これが実際に一方向の関係である場合は、mappedBy要素を削除して@JoinColumnonを指定する必要がありますMember

@Table(name="member")
public class Member implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(unique=true, nullable=false)
    private int id;

    @Column(name="date_of_birth")
    private Timestamp dateOfBirth;
    ...

    @OneToMany()
    @JoinColumn(name="id") //this depends on the name of the foreign key column
    private List<Username> usernames;
    ...
于 2013-05-09T00:18:31.993 に答える
0

おそらく、eager fetch タイプを使用してみる必要があります。

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
于 2015-05-12T14:05:08.237 に答える