JPAエンティティメタモデルを生成する方法


94

CriteriaQuery JPA 2.0に関連付けられているタイプセーフティの精神に基づいて、エンティティのメタモデル表現をサポートするAPIもあります。

このAPIの完全に機能する実装を知っている人はいますか(メタモデルクラスを手動で作成するのではなく、メタモデルを生成するため)。誰かがこれをEclipseで設定する手順も知っているとすばらしいでしょう(私は注釈プロセッサの設定と同じくらい簡単だと思いますが、あなたは決して知りません)。

編集:Hibernate JPA 2 Metamodel Generatorを偶然見つけました。しかし、jarのダウンロードリンクが見つからないため、問題は解決しません。

編集2:この質問をしてからしばらく経ちましたが、戻ってきてSourceForgeのHibernate JPA Model Generatorプロジェクトへのリンクを追加すると思いました

回答:


87

誰かがこれをEclipseで設定するための手順も知っているとすばらしいです(注釈プロセッサの設定と同じくらい簡単だと思いますが、あなたは決して知りません)。

はい、そうです。以下は、さまざまなJPA 2.0実装の実装と手順です。

EclipseLink

ハイバネート

OpenJPA

DataNucleus


最新のHibernate実装は次の場所で入手できます。

古いHibernate実装は次の場所にあります。


1
DataNucleusリンクは機能していません。
カールリヒター

1
Hibernateリンクも
Freelancer

43

jpa-metamodels-with-maven-exampleをご覧ください。

ハイバネート

  • 必要org.hibernate.org:hibernate-jpamodelgenです。
  • プロセッサクラスはorg.hibernate.jpamodelgen.JPAMetaModelEntityProcessorです。

依存関係としての休止状態

    <dependency>
      <groupId>org.hibernate.orm</groupId>
      <artifactId>hibernate-jpamodelgen</artifactId>
      <version>${version.hibernate-jpamodelgen}</version>
      <scope>provided</scope>
    </dependency>

プロセッサとしての休止状態

      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <compilerArguments>-AaddGeneratedAnnotation=false</compilerArguments> <!-- suppress java.annotation -->
              <processors>
                <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
              </processors>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>${version.hibernate-jpamodelgen}</version>
          </dependency>
        </dependencies>
      </plugin>

OpenJPA

  • 必要org.apache.openjpa:openjpaです。
  • プロセッサクラスはorg.apache.openjpa.persistence.meta.AnnotationProcessor6です。
  • OpenJPAには追加の要素が必要なようです<openjpa.metamodel>true<openjpa.metamodel>

依存関係としてのOpenJPA

  <dependencies>
    <dependency>
      <groupId>org.apache.openjpa</groupId>
      <artifactId>openjpa</artifactId>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <compilerArgs>
            <arg>-Aopenjpa.metamodel=true</arg>
          </compilerArgs>
        </configuration>
      </plugin>
    </plugins>
  </build>

プロセッサーとしてのOpenJPA

      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
          <execution>
            <id>process</id>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <processors>
                <processor>org.apache.openjpa.persistence.meta.AnnotationProcessor6</processor>
              </processors>
              <optionMap>
                <openjpa.metamodel>true</openjpa.metamodel>
              </optionMap>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa</artifactId>
            <version>${version.openjpa}</version>
          </dependency>
        </dependencies>
      </plugin>

EclipseLink

  • 必要org.eclipse.persistence:org.eclipse.persistence.jpa.modelgen.processorです。
  • プロセッサクラスはorg.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessorです。
  • EclipseLinkにはが必要persistence.xmlです。

依存関係としてのEclipseLink

  <dependencies>
    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
      <scope>provided</scope>
    </dependency>

プロセッサーとしてのEclipseLink

    <plugins>
      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <processors>
                <processor>org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor</processor>
              </processors>
              <compilerArguments>-Aeclipselink.persistencexml=src/main/resources-${environment.id}/META-INF/persistence.xml</compilerArguments>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
            <version>${version.eclipselink}</version>
          </dependency>
        </dependencies>
      </plugin>

DataNucleus

  • 必要org.datanucleus:datanucleus-jpa-queryです。
  • プロセッサクラスはorg.datanucleus.jpa.query.JPACriteriaProcessorです。

依存関係としてのDataNucleus

  <dependencies>
    <dependency>
      <groupId>org.datanucleus</groupId>
      <artifactId>datanucleus-jpa-query</artifactId>
      <scope>provided</scope>
    </dependency>
  </dependencies>

プロセッサとしてのDataNucleus

      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
          <execution>
            <id>process</id>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <processors>
                <processor>org.datanucleus.jpa.query.JPACriteriaProcessor</processor>
              </processors>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-jpa-query</artifactId>
            <version>${version.datanucleus}</version>
          </dependency>
        </dependencies>
      </plugin>

3
ただ、明確にするために、生成されたものは、私は、NetBeans 8からのメタモデルを生成couldntの、あなたはそれを生成するために休止状態使用していても、EclipseLinkを一緒に使用し、私のものを生成するMavenのテストプロジェクトを作成しなければならなかったことができる
Kalpesh曽爾を

@ymajoros something is recommendedなしで言うことはSOで禁止されていIMHOますか?私は他の誰かのために代理をしているのではありません。
ジンクォン

1
ところで、EclipseLinkのソーターの答えを見てください。これは私が長年使用してきた構成であり、完全に機能します。stackoverflow.com/questions/3037593/...
ymajoros

私はEclipseLinkを使ったHibernate生成メタモデルを使用し、NullPointerExceptionが取得しようと、この実装固有のものではない
のMichałZiobro

@ymajorosにはまだが必要persistence.xmlですよね?
ジンクォン

20

DaliによるEclipseのJPA 2.0サポート(「JEE開発者向けEclipse IDE」に含まれています)には、Eclipseと統合された独自のメタモデルジェネレーターがあります。

  1. パッケージエクスプローラーでプロジェクトを選択します
  2. [ プロパティ ] -> [ JPA ]ダイアログに移動します
  3. Canonical metamodel(JPA 2.0)グループからソースフォルダーを選択
  4. [ 適用 ]ボタンをクリックして、選択したソースフォルダにメタモデルクラスを生成します

ここに画像の説明を入力してください

生成されたクラスは標準であるため、これはどのJPAプロバイダーでも機能するはずです。

こちらもご覧ください


自分でプロセスを開始する方法はありますか?これは私にとってメタモデルを確実に生成するわけではありません
thatsIch

6

eclipselinkの場合、メタモデルを生成するには、次の依存関係のみで十分です。他には何も必要ありません。

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.5.1</version>
        <scope>provided</scope>
    </dependency>


@Barthelomeusあなたのメモはです。EclipseLink 2.5.1以降では、リストにないエンティティのメタモデルクラスも生成されます<exclude-unlisted-classes>false</exclude-unlisted-classes>。persistetence.xmlで指定するだけです
Michele Mariotti

eclipselinkは、なしでは生成されないことに注意してくださいpersistence.xml
Jin Kwon

5

最も一般的なIMHOであるプロバイダーとしてのHibernateの場合:

Gradle、Mavenなどのビルドツールの場合、クラスパスにHibernate JPA 2メタモデルジェネレーターjarが必要であり、コンパイラーレベル> = 1.6でプロジェクトをビルドすると、メタモデルが自動的に生成されます。

IDE Eclipseの場合1. [プロジェクト]-> [プロパティ]-> [Javaコンパイラ]-> [注釈処理]に移動して有効にします。2.「注釈処理」->「ファクトリパス」->「外部JARの追加」を展開し、Hibernate JPA 2メタモデルジェネレーターjarを追加します。新しく追加されたjarを確認し、「OK」と言います。クリーンとビルドが完了しました!

リンクHibernate JPA 2メタモデルジェネレーターjarリンク(maven repoから) https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen


私の場合<dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-jpamodelgen</artifactId> <scope>compile</scope> </dependency> </dependencies>、pom.xmlに追加するだけで十分でした。
Lu55、18年

MavenとEclipseを使用する場合、両方の構成が必要ですか?
メルコール

hibernate-jpamodelgenがpomに追加されたとしても、私はこれを行わなければならず、うまくいきました
Freelancer

3

これは非常に一般的な質問であるため、この回答に基づいてこの記事を書きました。

私たちのアプリケーションは、以下の使用を前提としましょうPostPostCommentPostDetails、およびTag1対多を形成するエンティティ、1対1、および多対多のテーブルのリレーションを

JPA基準メタモデル

JPA基準メタモデルを生成する方法

hibernate-jpamodelgenHibernateはORMが提供するツールは、プロジェクトのエンティティをスキャンし、JPA基準メタモデルを生成するために使用することができます。Maven 構成ファイルのに以下annotationProcessorPathを追加するだけです。maven-compiler-pluginpom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${maven-compiler-plugin.version}</version>
    <configuration>
        <annotationProcessorPaths>
            <annotationProcessorPath>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-jpamodelgen</artifactId>
                <version>${hibernate.version}</version>
            </annotationProcessorPath>
        </annotationProcessorPaths>
    </configuration>
</plugin>

これで、プロジェクトがコンパイルされると、targetフォルダー内に次のJavaクラスが生成されていることがわかります。

> tree target/generated-sources/
target/generated-sources/
└── annotations
    └── com
        └── vladmihalcea
            └── book
                └── hpjp
                    └── hibernate
                        ├── forum
                           ├── PostComment_.java
                           ├── PostDetails_.java
                           ├── Post_.java
                           └── Tag_.java

タグエンティティメタモデル

場合はTag、次のようにエンティティがマップされます。

@Entity
@Table(name = "tag")
public class Tag {

    @Id
    private Long id;

    private String name;

    //Getters and setters omitted for brevity
}

Tag_メタモデルクラスは、このように生成されます。

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

    public static volatile SingularAttribute<Tag, String> name;
    public static volatile SingularAttribute<Tag, Long> id;

    public static final String NAME = "name";
    public static final String ID = "id";
}

SingularAttribute基本的に使用されるidname TagJPAエンティティ属性。

エンティティメタモデルの投稿

Postエンティティは次のようにマッピングされます。

@Entity
@Table(name = "post")
public class Post {

    @Id
    private Long id;

    private String title;

    @OneToMany(
        mappedBy = "post",
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    private List<PostComment> comments = new ArrayList<>();

    @OneToOne(
        mappedBy = "post",
        cascade = CascadeType.ALL,
        fetch = FetchType.LAZY
    )
    @LazyToOne(LazyToOneOption.NO_PROXY)
    private PostDetails details;

    @ManyToMany
    @JoinTable(
        name = "post_tag",
        joinColumns = @JoinColumn(name = "post_id"),
        inverseJoinColumns = @JoinColumn(name = "tag_id")
    )
    private List<Tag> tags = new ArrayList<>();

    //Getters and setters omitted for brevity
}

Postエンティティは、2つの基本的な属性を持ち、idかつtitle、1対多のcommentsコレクション、1対1 detailsの関連、および多対多tagsのコレクションを。

Post_次のようにメタモデルクラスが生成されます。

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

    public static volatile ListAttribute<Post, PostComment> comments;
    public static volatile SingularAttribute<Post, PostDetails> details;
    public static volatile SingularAttribute<Post, Long> id;
    public static volatile SingularAttribute<Post, String> title;
    public static volatile ListAttribute<Post, Tag> tags;

    public static final String COMMENTS = "comments";
    public static final String DETAILS = "details";
    public static final String ID = "id";
    public static final String TITLE = "title";
    public static final String TAGS = "tags";
}

基本idtitle属性、および1対1のdetails関連付けはaで表されSingularAttributecommentsおよびtagsコレクションはJPAで表されListAttributeます。

PostDetailsエンティティメタモデル

PostDetailsエンティティは次のようにマッピングされます。

@Entity
@Table(name = "post_details")
public class PostDetails {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "created_on")
    private Date createdOn;

    @Column(name = "created_by")
    private String createdBy;

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    @JoinColumn(name = "id")
    private Post post;

    //Getters and setters omitted for brevity
}

すべてのエンティティー属性はSingularAttribute、関連するPostDetails_MetamodelクラスのJPAによって表されます。

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

    public static volatile SingularAttribute<PostDetails, Post> post;
    public static volatile SingularAttribute<PostDetails, String> createdBy;
    public static volatile SingularAttribute<PostDetails, Long> id;
    public static volatile SingularAttribute<PostDetails, Date> createdOn;

    public static final String POST = "post";
    public static final String CREATED_BY = "createdBy";
    public static final String ID = "id";
    public static final String CREATED_ON = "createdOn";
}

PostCommentエンティティメタモデル

PostComment次のようにマップされます。

@Entity
@Table(name = "post_comment")
public class PostComment {

    @Id
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private Post post;

    private String review;

    //Getters and setters omitted for brevity
}

また、すべてのエンティティー属性はSingularAttribute、関連するPostComments_MetamodelクラスのJPAによって表されます。

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

    public static volatile SingularAttribute<PostComment, Post> post;
    public static volatile SingularAttribute<PostComment, String> review;
    public static volatile SingularAttribute<PostComment, Long> id;

    public static final String POST = "post";
    public static final String REVIEW = "review";
    public static final String ID = "id";
}

JPA基準メタモデルの使用

JPAメタモデルがない場合、PostComment関連するPostタイトルでフィルタリングされたエンティティをフェッチする必要があるCriteria APIクエリは次のようになります。

CriteriaBuilder builder = entityManager.getCriteriaBuilder();

CriteriaQuery<PostComment> query = builder.createQuery(PostComment.class);
Root<PostComment> postComment = query.from(PostComment.class);

Join<PostComment, Post> post = postComment.join("post");

query.where(
    builder.equal(
        post.get("title"),
        "High-Performance Java Persistence"
    )
);

List<PostComment> comments = entityManager
    .createQuery(query)
    .getResultList();

インスタンスをpost作成するときに文字列リテラルJoinを使用し、をtitle参照するときに文字列リテラルを使用したことに注意してくださいPost title

JPAメタモデルを使用すると、次の例に示すように、エンティティ属性のハードコーディングを回避できます。

CriteriaBuilder builder = entityManager.getCriteriaBuilder();

CriteriaQuery<PostComment> query = builder.createQuery(PostComment.class);
Root<PostComment> postComment = query.from(PostComment.class);

Join<PostComment, Post> post = postComment.join(PostComment_.post);

query.where(
    builder.equal(
        post.get(Post_.title),
        "High-Performance Java Persistence"
    )
);

List<PostComment> comments = entityManager
    .createQuery(query)
    .getResultList();

Codotaのようなコード補完ツールを使用している場合、JPA基準APIクエリの記述ははるかに簡単です。チェックアウトこの記事を Codota IDEプラグインの詳細については。

または、フィルター処理中にDTOプロジェクションをフェッチするPost titleとします。PostDetails createdOn属性ます。

結合属性を作成するとき、およびDTOプロジェクション列のエイリアスを構築するとき、またはフィルタリングする必要があるエンティティ属性を参照するときに、メタモデルを使用できます。

CriteriaBuilder builder = entityManager.getCriteriaBuilder();

CriteriaQuery<Object[]> query = builder.createQuery(Object[].class);

Root<PostComment> postComment = query.from(PostComment.class);
Join<PostComment, Post> post = postComment.join(PostComment_.post);

query.multiselect(
    postComment.get(PostComment_.id).alias(PostComment_.ID),
    postComment.get(PostComment_.review).alias(PostComment_.REVIEW),
    post.get(Post_.title).alias(Post_.TITLE)
);

query.where(
    builder.and(
        builder.like(
            post.get(Post_.title),
            "%Java Persistence%"
        ),
        builder.equal(
            post.get(Post_.details).get(PostDetails_.CREATED_BY),
            "Vlad Mihalcea"
        )
    )
);

List<PostCommentSummary> comments = entityManager
    .createQuery(query)
    .unwrap(Query.class)
    .setResultTransformer(Transformers.aliasToBean(PostCommentSummary.class))
    .getResultList();

かっこいいですよね?


0

わかりました。ここで読んだ内容に基づいて、EclipseLinkをこの方法で実行しました。プロジェクトにプロセッサの依存関係を置く必要はなくannotationProcessorPath、コンパイラプラグインの要素としてのみ使用しました。

    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <annotationProcessorPaths>
                <annotationProcessorPath>
                    <groupId>org.eclipse.persistence</groupId>
                    <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
                    <version>2.7.7</version>
                </annotationProcessorPath>
            </annotationProcessorPaths>
            <compilerArgs>
                <arg>-Aeclipselink.persistencexml=src/main/resources/META-INF/persistence.xml</arg>
            </compilerArgs>
        </configuration>
    </plugin>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.