Java 如何生成JPA实体元模型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3037593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to generate the JPA entity Metamodel?
提问by Andrey
In the spirit of type safety associated with the CriteriaQueryJPA 2.0 also has an API to support Metamodelrepresentation of entities.
本着与CriteriaQuery相关的类型安全的精神,JPA 2.0 也有一个 API 来支持实体的元模型表示。
Is anyone aware of a fully functional implementation of this API (to generate the Metamodel as opposed to creating the metamodel classes manually)? It would be awesome if someone also knows the steps for setting this up in Eclipse (I assume it's as simple as setting up an annotation processor, but you never know).
有没有人知道这个 API 的全功能实现(生成元模型而不是手动创建元模型类)?如果有人也知道在 Eclipse 中进行设置的步骤,那就太棒了(我认为它就像设置注释处理器一样简单,但你永远不知道)。
EDIT: Just stumbled across Hibernate JPA 2 Metamodel Generator . But the issue remains since I can't find any download links for the jar.
编辑:刚刚偶然发现Hibernate JPA 2 Metamodel Generator。但问题仍然存在,因为我找不到 jar 的任何下载链接。
EDIT 2: Awhile has passed since I asked this question, but I thought I'd come back and add a link to the Hibernate JPA Model Generator project on SourceForge
编辑 2:自从我问这个问题以来已经过去了一段时间,但我想我会回来并在 SourceForge 上添加一个指向Hibernate JPA 模型生成器项目的链接
采纳答案by Pascal Thivent
It would be awesome if someone also knows the steps for setting this up in Eclipse (I assume it's as simple as setting up an annotation processor, but you never know)
如果有人也知道在 Eclipse 中设置它的步骤,那就太棒了(我认为它就像设置注释处理器一样简单,但你永远不知道)
Yes it is. Here are the implementations and instructions for the various JPA 2.0 implementations:
是的。以下是各种 JPA 2.0 实现的实现和说明:
EclipseLink
Eclipse链接
Hibernate
休眠
org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
- http://in.relation.to/2009/11/09/hibernate-static-metamodel-generator-annotation-processor
org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
- http://in.relation.to/2009/11/09/hibernate-static-metamodel-generator-annotation-processor
OpenJPA
开放式JPA
org.apache.openjpa.persistence.meta.AnnotationProcessor6
- http://openjpa.apache.org/builds/2.4.1/apache-openjpa/docs/ch13s04.html
org.apache.openjpa.persistence.meta.AnnotationProcessor6
- http://openjpa.apache.org/builds/2.4.1/apache-openjpa/docs/ch13s04.html
DataNucleus
数据核
org.datanucleus.jpa.JPACriteriaProcessor
- http://www.datanucleus.org/products/accessplatform_2_1/jpa/jpql_criteria_metamodel.html
org.datanucleus.jpa.JPACriteriaProcessor
- http://www.datanucleus.org/products/accessplatform_2_1/jpa/jpql_criteria_metamodel.html
The latest Hibernate implementation is available at:
最新的 Hibernate 实现可在以下位置获得:
An older Hibernate implementation is at:
较旧的 Hibernate 实现位于:
回答by Jin Kwon
Please take a look at jpa-metamodels-with-maven-example.
请看一下jpa-metamodels-with-maven-example。
Hibernate
休眠
- We need
org.hibernate.org:hibernate-jpamodelgen
. - The processor class is
org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
.
- 我们需要
org.hibernate.org:hibernate-jpamodelgen
. - 处理器类是
org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
.
Hibernate as a dependency
Hibernate 作为依赖
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${version.hibernate-jpamodelgen}</version>
<scope>provided</scope>
</dependency>
Hibernate as a processor
作为处理器休眠
<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
开放式JPA
- We need
org.apache.openjpa:openjpa
. - The processor class is
org.apache.openjpa.persistence.meta.AnnotationProcessor6
. - OpenJPA seems require additional element
<openjpa.metamodel>true<openjpa.metamodel>
.
- 我们需要
org.apache.openjpa:openjpa
. - 处理器类是
org.apache.openjpa.persistence.meta.AnnotationProcessor6
. - OpenJPA 似乎需要额外的元素
<openjpa.metamodel>true<openjpa.metamodel>
。
OpenJPA as a dependency
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 as a processor
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
Eclipse链接
- We need
org.eclipse.persistence:org.eclipse.persistence.jpa.modelgen.processor
. - The processor class is
org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor
. - EclipseLink requires
persistence.xml
.
- 我们需要
org.eclipse.persistence:org.eclipse.persistence.jpa.modelgen.processor
. - 处理器类是
org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor
. - EclipseLink 需要
persistence.xml
.
EclipseLink as a dependency
EclipseLink 作为依赖项
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
<scope>provided</scope>
</dependency>
EclipseLink as a processor
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
数据核
- We need
org.datanucleus:datanucleus-jpa-query
. - The processor class is
org.datanucleus.jpa.query.JPACriteriaProcessor
.
- 我们需要
org.datanucleus:datanucleus-jpa-query
. - 处理器类是
org.datanucleus.jpa.query.JPACriteriaProcessor
.
DataNucleus as a dependency
DataNucleus 作为依赖项
<dependencies>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-jpa-query</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
DataNucleus as a processor
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>
回答by James
Eclipse's JPA 2.0 support through Dali (which is included in "Eclipse IDE for JEE Developers") has its own metamodel generator integrated with Eclipse.
Eclipse 通过 Dali 提供的 JPA 2.0 支持(包含在“Eclipse IDE for JEE Developers”中)具有与 Eclipse 集成的自己的元模型生成器。
- Select your project in the Package Explorer
- Go to Properties-> JPAdialog
- Select source folder from Canonical metamodel (JPA 2.0)group
- Click Applybutton to generate metamodel classes in the selected source folder
- 在Package Explorer 中选择您的项目
- 转到“属性”->“ JPA”对话框
- 从规范元模型 (JPA 2.0)组中选择源文件夹
- 单击应用按钮在选定的源文件夹中生成元模型类
This should work on any JPA provider as the generated classes are standard.
这应该适用于任何 JPA 提供程序,因为生成的类是标准的。
Also see here.
另请参阅此处。
回答by Sorter
For eclipselink, only the following dependency is sufficient to generate metamodel. Nothing else is needed.
对于eclipselink,只需要以下依赖就足以生成元模型。不需要其他任何东西。
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
<version>2.5.1</version>
<scope>provided</scope>
</dependency>
回答by SandeepGodara
For Hibernate as provider which is most common IMHO:
对于 Hibernate 作为提供者,这是最常见的恕我直言:
In case of build tools like Gradle, Maven you need to have Hibernate JPA 2 Metamodel Generator jar in the classpath and compiler level>=1.6 that is all you need build the project and metamodel will be generated automatically.
对于 Gradle、Maven 等构建工具,您需要在类路径和编译器级别>=1.6 中拥有 Hibernate JPA 2 Metamodel Generator jar,这就是您构建项目所需的全部内容,元模型将自动生成。
In case of IDE Eclipse 1. goto Project->Properties->Java Compiler->Annotation Processing and enable it. 2. Expand Annotation Processing->Factory Path-> Add External Jar add Hibernate JPA 2 Metamodel Generator jar check the newly added jar and say OK. Clean and Build done!
如果是 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。清洁和构建完成!
Link Hibernate JPA 2 Metamodel Generator jar link from maven repo https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen
链接来自 maven repo https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen 的Hibernate JPA 2 Metamodel Generator jar 链接
回答by Vlad Mihalcea
Since this is a very common question, I wrote this article, on which this answer is based on.
由于这是一个非常常见的问题,我写了这篇文章,这个答案是基于它。
Let's assume our application uses the following Post
, PostComment
, PostDetails
, and Tag
entities, which form a one-to-many, one-to-one, and many-to-many table relationships:
假设我们的应用程序使用以下Post
、PostComment
、PostDetails
和Tag
实体,它们形成一对多、一对一和多对多表关系:
How to generate the JPA Criteria Metamodel
如何生成 JPA 标准元模型
The hibernate-jpamodelgen
tool provided by Hibernate ORM can be used to scan the project entities and generate the JPA Criteria Metamodel. All you need to do is add the following annotationProcessorPath
to the maven-compiler-plugin
in the Maven pom.xml
configuration file:
hibernate-jpamodelgen
Hibernate ORM 提供的工具可用于扫描项目实体并生成 JPA Criteria Metamodel。您需要做的就是将以下内容添加annotationProcessorPath
到maven-compiler-plugin
Mavenpom.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>
Now, when the project is compiled, you can see that in the target
folder, the following Java classes are generated:
现在,当编译项目时,您可以看到在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 Metamodel
标签实体元模型
If the Tag
entity is mapped as follows:
如果Tag
实体映射如下:
@Entity
@Table(name = "tag")
public class Tag {
@Id
private Long id;
private String name;
//Getters and setters omitted for brevity
}
The Tag_
Metamodel class is generated like this:
该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";
}
The SingularAttribute
is used for the basic id
and name
Tag
JPA entity attributes.
该SingularAttribute
用于基本id
和name
Tag
JPA实体的属性。
Post entity Metamodel
发布实体元模型
The Post
entity is mapped like this:
在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
}
The Post
entity has two basic attributes, id
and title
, a one-to-many comments
collection, a one-to-one details
association, and a many-to-many tags
collection.
该Post
实体有两个基本属性,id
并且title
,一到多的comments
集合,一个对一个details
的关联,和许多一对多的tags
集合。
The Post_
Metamodel class is generated as follows:
该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";
}
The basic id
and title
attributes, as well as the one-to-one details
association, are represented by a SingularAttribute
while the comments
and tags
collections are represented by the JPA ListAttribute
.
基本id
和title
属性以及一对一details
关联由 a SingularAttribute
whilecomments
和tags
集合由 JPA 表示ListAttribute
。
PostDetails entity Metamodel
PostDetails 实体元模型
The PostDetails
entity is mapped like this:
在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
}
All entity attributes are going to be represented by the JPA SingularAttribute
in the associated PostDetails_
Metamodel class:
所有实体属性都将由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 entity Metamodel
PostComment 实体元模型
The PostComment
is mapped as follows:
的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
}
And, all entity attributes are represented by the JPA SingularAttribute
in the associated PostComments_
Metamodel class:
并且,所有实体属性都由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";
}
Using the JPA Criteria Metamodel
使用 JPA 标准元模型
Without the JPA Metamodel, a Criteria API query that needs to fetch the PostComment
entities filtered by their associated Post
title would look like this:
如果没有 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();
Notice that we used the post
String literal when creating the Join
instance, and we used the title
String literal when referencing the Post
title
.
请注意,我们post
在创建Join
实例时使用了字符串字面量,而title
在引用Post
title
.
The JPA Metamodel allows us to avoid hard-coding entity attributes, as illustrated by the following example:
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();
Writing JPA Criteria API queries is much easier if you are using a code completion tool like Codota. Check out this articlefor more details about the Codota IDE plugin.
如果您使用像 Codota 这样的代码完成工具,编写 JPA Criteria API 查询会容易得多。查看这篇文章,了解有关 Codota IDE 插件的更多详细信息。
Or, let's say we want to fetch a DTO projectionwhile filtering the Post
title
and the PostDetails
createdOn
attributes.
或者,假设我们想要在过滤和属性时获取DTO 投影。Post
title
PostDetails
createdOn
We can use the Metamodel when creating the join attributes, as well as when building the DTO projection column aliases or when referencing the entity attributes we need to filter:
我们可以在创建连接属性时使用元模型,以及在构建 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();
Cool, right?
酷,对吧?
回答by dmatej
Ok, based on what I have read here, I did it with EclipseLinkthis way and I did not need to put the processor dependency to the project, only as an annotationProcessorPath
element of the compiler plugin.
好的,根据我在这里读到的内容,我用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>