如何生成JPA 2.0元模型?

And*_*rey 89 java jpa annotation-processing metamodel jpa-2.0

本着与CriteriaQuery相关的类型安全的精神,JPA 2.0还有一个API来支持实体的Metamodel表示.

是否有人知道这个API的全功能实现(生成Metamodel而不是手动创建元模型类)?如果有人也知道在Eclipse中设置它的步骤,那将是非常棒的(我假设它就像设置注释处理器一样简单,但你永远不知道).

编辑:偶然发现了Hibernate JPA 2 Metamodel Generator.但问题仍然存在,因为我找不到jar的任何下载链接.

编辑2:少顷已经过去了,因为我问过这个问题,但我想我会回来,并添加一个链接到SourceForge上的Hibernate JPA模型生成项目

Pas*_*ent 86

如果有人也知道在Eclipse中设置它的步骤会很棒(我假设它就像设置注释处理器一样简单,但你永远不知道)

是的.以下是各种JPA 2.0实现的实现和说明:

的EclipseLink

过冬

OpenJPA的

DataNucleus将


最新的Hibernate实现可在以下位置获得:

较旧的Hibernate实现位于:


Jin*_*won 41

修订(2014年3月)

请查看jpa-metamodels-with-maven

过冬

最推荐使用Hibernate.

(我不判断这些实现上的任何特性/功能/可用性/稳定性.上面的语句只关注我构建的maven用法.)

    <dependency>
      <groupId>org.hibernate.orm</groupId>
      <artifactId>hibernate-jpamodelgen</artifactId>
      <version>${version.hibernate-jpamodelgen}</version>
      <scope>provided</scope>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

OpenJPA的

OpenJPA似乎需要额外的元素org.hibernate.org:hibernate-jpamodelgen.

      <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>
Run Code Online (Sandbox Code Playgroud)

的EclipseLink

EclipseLink需要org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor.

  <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>
Run Code Online (Sandbox Code Playgroud)

========================================

对于Apache Maven用户,

以下简单配置似乎有效.(使用旧的maven-compiler-plugin;更新.)

      <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>
Run Code Online (Sandbox Code Playgroud)

你可以用"mvn编译器:编译"来运行它

UPDATE

请注意,此方法仅适用于那些旧的maven-compiler-plugin.检查代码中的版本.

  • 为了清楚起见,生成的东西可以与eclipselink一起使用,即使你使用hibernate生成它,我也无法从netbeans 8生成元模型,并且必须创建一个maven测试项目来生成我的东西 (3认同)

Jam*_*mes 18

Eclipse的JPA 2.0支持通过Dali(包含在"Eclipse IDE for JEE Developers"中)拥有自己的与Eclipse集成的元模型生成器.

  1. Package Explorer中选择您的项目
  2. 转到属性 - > JPA对话框
  3. Canonical元模型(JPA 2.0)组中选择源文件夹
  4. 单击" 应用"按钮以在所选源文件夹中生成元模型类

在此输入图像描述

这应该适用于任何JPA提供程序,因为生成的类是标准的.

另见这里.


Vla*_*cea 11

假设我们的应用程序使用以下PostPostCommentPostDetailsTag实体,它们形成一对多、一对一和多对多表关系:

JPA 标准元模型

如何生成 JPA 标准元模型

hibernate-jpamodelgenHibernate ORM 提供的工具可用于扫描项目实体并生成 JPA Criteria Metamodel。您需要做的就是将以下内容添加annotationProcessorPathmaven-compiler-pluginMavenpom.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>
Run Code Online (Sandbox Code Playgroud)

现在,当编译项目时,您可以看到在target文件夹中,生成了以下 Java 类:

> tree target/generated-sources/
target/generated-sources/
??? annotations
    ??? com
        ??? vladmihalcea
            ??? book
                ??? hpjp
                    ??? hibernate
                        ??? forum
                        ?   ??? PostComment_.java
                        ?   ??? PostDetails_.java
                        ?   ??? Post_.java
                        ?   ??? Tag_.java
Run Code Online (Sandbox Code Playgroud)

标签实体元模型

如果Tag实体映射如下:

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

    @Id
    private Long id;

    private String name;

    //Getters and setters omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)

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";
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

Post实体有两个基本属性,id并且title,一到多的comments集合,一个对一个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";
}
Run Code Online (Sandbox Code Playgroud)

基本idtitle属性以及一对一details关联由 a SingularAttributewhilecommentstags集合由 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
}
Run Code Online (Sandbox Code Playgroud)

所有实体属性都将由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";
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

并且,所有实体属性都由SingularAttribute关联的PostComments_元模型类中的 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";
}
Run Code Online (Sandbox Code Playgroud)

使用 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();
Run Code Online (Sandbox Code Playgroud)

请注意,我们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();
Run Code Online (Sandbox Code Playgroud)

或者,假设我们想要在过滤Post titlePostDetails createdOn属性时获取 DTO 投影。

我们可以在创建连接属性时使用元模型,以及在构建 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();
Run Code Online (Sandbox Code Playgroud)

酷,对吧?


Sor*_*ter 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>
Run Code Online (Sandbox Code Playgroud)


San*_*ara 6

对于 Hibernate 作为提供者,这是最常见的恕我直言:

对于像 Gradle、Maven 这样的构建工具,您需要在类路径和编译器级别>=1.6 中拥有 Hibernate JPA 2 Metamodel Generator jar,这就是您构建项目所需的全部内容,元模型将自动生成。

如果是 IDE Eclipse 1. 转到 Project->Properties->Java Compiler->Annotation Processing 并启用它。2. 展开Annotation Processing->Factory Path-> Add External Jar add Hibernate JPA 2 Metamodel Generator jar 勾选新添加的jar并说OK。清洁和构建完成!

链接来自 maven repo https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen 的Hibernate JPA 2 Metamodel Generator jar 链接