7

findJava EE 6 で、エンティティのプライマリ ID とともにJPA EntityManager のメソッドを使用すると null が返されるというかなり奇妙なケースに遭遇しましたが、Criteria API を使用してその ID を持つすべてのエンティティを選択すると正常に動作します。

私が使用しているコードは次のfindとおりです。

// Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);

...そして、これが Criteria API で使用しているコードです。

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> u = criteria.from(User.class);
TypedQuery<User> query = em.createQuery(
    criteria.select(u).where(builder.equal(u.get("id"), userId)));
user = query.getSingleResult();

なぜfindnullを返すのにCriteriaがユーザーを見つけるのか考えていますか? プログラムのまったく同じ場所で、これら 2 つの代替方法を試しました。

User エンティティの関連部分は次のとおりです。

@Entity
@Table(name = "USERS")
@Access(AccessType.PROPERTY)
public class User implements Serializable {
    ...
    private Long id;
    ...
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_generator")
    @SequenceGenerator(name = "user_id_generator", sequenceName = "user_sequence", allocationSize = 1)
    @Column(name="id")
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    ...
}
4

6 に答える 6

12

私は問題を理解しました。これは、データベース内のフィールドnullが許可されるべきではなかったためです。これは私が手作業で編集したためです。そのフィールドに値を追加すると、問題は解決しました。

于 2010-07-09T15:26:08.977 に答える
3

どのプロバイダを使用していますか?

トランザクションの内外で、この検索をどこで実行していますか? 検出前に EM をフラッシュしてクリアしていますか?

EclipseLink をプロバイダーとして使用し、私自身の同様のモデルを使用しても、これを再現できません。

プロバイダーが SQL をログに記録できると仮定すると、検索時に SQL が DB に送信されていることがわかりますか? SQL はどのように表示され、SQL Plus などで適切に実行されますか?

于 2010-07-08T16:23:02.583 に答える
3

解決策を確認します。同じことが私にも起こりました。としてマークされた列がNOT NULLあり、アプリでのテスト中に、2 つの列 (外部キー) のデータベースで制限をオフに切り替えましたが、エンティティ クラスoptional = falseの関係の ( ) 属性は変更しませんでした。@ManyToOne属性を削除した後、モデルがデータベースと一致するようになり、すべてが正常に機能し始めました。環境が何らかの警告や例外を生成しないのは奇妙です。

于 2014-02-11T22:54:15.763 に答える
1

Long次のスニペットでa を渡していることを再確認してください。

// Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);

これで問題が解決しない場合は、SQL ログを有効にして何が起こっているかを確認し、両方のケースでの動作を比較してください。

于 2010-07-08T16:44:23.443 に答える
0

サニティ チェックとしてコードをデバッグし、find を実行する前にデータベースに対して手動クエリを実行して、期待する ID を持つ適切なユーザー レコードが存在することを確認します。

データベースにない場合は、エンティティ マネージャーがフラッシュされているか、現在のトランザクションがコミットされていることを確認してください。

たとえば、Hibernate をプロバイダーとして使用している場合、オブジェクトが単にキャッシュに「保持」され、変更が実際にはデータベースにプッシュされていない可能性があります。したがって、Hibernate の実装を通過する基準はオブジェクトを取得しますが、エンティティ マネージャーの検索ではオブジェクトを見つけることができません。

于 2010-07-08T16:42:09.833 に答える
0

1 つの理由として、「id」フィールドが User エンティティの ID として正しくマークされていないことが考えられます。

于 2010-07-08T15:48:32.390 に答える