1. 概要

このチュートリアルでは、Hibernateで基準クエリを記述しながらJPA静的メタモデルクラスを使用する方法について説明します。

Hibernateの基準クエリAPIの基本を理解する必要があるため、必要に応じて、基準クエリのチュートリアルでこのトピックの詳細を確認してください。

2. なぜJPAメタモデルなのか?

多くの場合、基準クエリを作成するときは、エンティティクラスとその属性を参照する必要があります。

現在、これを行う方法の1つは、属性の名前を文字列として提供することです。 しかし、これにはいくつかの欠点があります。

1つは、エンティティ属性の名前を検索する必要があります。 また、プロジェクトのライフサイクルの後半で列名が変更された場合は、名前が使用されている各クエリをリファクタリングする必要があります。

JPAメタモデルは、これらの欠点を回避し、管理対象エンティティクラスのメタデータへの静的アクセスを提供するためにコミュニティによって導入されました。

3. エンティティクラス

クライアントの1人に学生ポータル管理システムを構築しているシナリオを考えてみましょう。卒業年に基づいて学生に検索機能を提供する必要があります。

まず、Studentクラスを見てみましょう。

@Entity
@Table(name = "students")
public class Student {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "grad_year")
    private int gradYear;

    // standard getters and setters
}

4. JPAメタモデルクラスの生成

次に、メタモデルクラスを生成する必要があります。この目的のために、JBossが提供するメタモデルジェネレーターツールを使用します。 JBossは、メタモデルを生成するために利用できる多くのツールの1つにすぎません。 その他の適切なツールには、 EclipseLink OpenJPA 、およびDataNucleusが含まれます。

JBossツールを使用するには、最新の依存関係 pom.xml ファイルに追加する必要があります。mavenビルドコマンドをトリガーすると、ツールはメタモデルクラスを生成します。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jpamodelgen</artifactId>
    <version>5.3.7.Final</version>
</dependency>

デフォルトでは、クラスはこのフォルダーでのみ生成されるため、 target/generated-classesフォルダーをIDEのクラスパスに追加する必要があることに注意してください。

5. 静的JPAメタモデルクラス

JPA仕様に基づいて、生成されたクラスは、対応するエンティティクラスと同じパッケージに存在し、最後に「_」(アンダースコア)が追加された同じ名前になります。 したがって、Studentクラス用に生成されたメタモデルクラスは Student_ になり、次のようになります。

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Student.class)
public abstract class Student_ {

    public static volatile SingularAttribute<Student, String> firstName;
    public static volatile SingularAttribute<Student, String> lastName;
    public static volatile SingularAttribute<Student, Integer> id;
    public static volatile SingularAttribute<Student, Integer> gradYear;

    public static final String FIRST_NAME = "firstName";
    public static final String LAST_NAME = "lastName";
    public static final String ID = "id";
    public static final String GRAD_YEAR = "gradYear";
}

6. JPAメタモデルクラスの使用

属性への文字列参照を使用するのと同じ方法で静的メタモデルクラスを使用できます。条件クエリAPIは、文字列参照と属性を受け入れるオーバーロードされたメソッドを提供しますインターフェースの実装。

2015年に卒業したすべてのStudentsを取得する基準クエリを見てみましょう。

//session set-up code
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Student> criteriaQuery = cb.createQuery(Student.class);

Root<Student> root = criteriaQuery.from(Student.class);
criteriaQuery.select(root).where(cb.equal(root.get(Student_.gradYear), 2015));

Query<Student> query = session.createQuery(criteriaQuery);
List<Student> results = query.getResultList();

従来のgrad_year列名を使用する代わりに、Student_.gradYear参照を使用したことに注目してください。

7. 結論

この簡単な記事では、静的メタモデルクラスの使用方法と、前述のString参照を使用する従来の方法よりも静的メタモデルクラスが優先される理由を学びました。

このチュートリアルのソースコードは、Githubにあります。