Java 什么是@StaticMetamodel 和 SingularAttribute<Obj,Obj>?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19704407/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 19:32:05  来源:igfitidea点击:

What is @StaticMetamodel and SingularAttribute<Obj,Obj>?

javaspringhibernatejpadependency-injection

提问by MoienGK

I am trying to figure out this code for about two hours now, for example in below class what are these fields representing?

我现在想弄清楚这段代码大约两个小时,例如在下面的课程中这些字段代表什么?

import java.util.Date;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;
import java.util.UUID;

@StaticMetamodel(Address.class)
public class Address_ extends  {
    public static volatile SingularAttribute<Address, Long> id;
    public static volatile SingularAttribute<Address, UUID> personId;
    public static volatile SingularAttribute<Address, Person> person;
}

The Address.classis a java class which has the following definition:

Address.class是具有如下定义的Java类:

@Entity
@Table(name = "address", schema = "public")
public class Address{
    private Long id;
    private Person person;
    private UUID personId;
    //....
}

Can you, please, explain what are the @StaticMetamodeland @SingularAttributeannotations used for? It might be simple but I can't understand.

请您解释一下@StaticMetamodel@SingularAttribute注释的用途是什么?这可能很简单,但我无法理解。

采纳答案by Konstantin Yovkov

As per documentation:

根据文档

A static metamodel is a series of classes that "mirror" the entities and embeddables in the domain model and provide static access to the metadata about the mirrored class's attributes.

静态元模型是一系列类,它们“镜像”域模型中的实体和可嵌入项,并提供对有关镜像类属性的元数据的静态访问。

The static metamodel has the following properties:

静态元模型具有以下属性:

  • For each managed class Xin package p, a metamodel class X_in package pis created.
  • For every persistent non-collection-valued attribute ydeclared by class X, where the type of yis Y, the metamodel class must contain a declaration as follows:
  • 对于Xpackage 中的每个托管类,都会在 package中创建p一个元模型类。X_p
  • 对于yclass 声明的每个持久性非集合值属性X,其中的类型yY,元模型类必须包含如下声明:

SingularAttributeexample:

SingularAttribute例子:

public static volatile SingularAttribute<X, Y> y;

The static metamodel is useful for creating type-safe querieswith the JPA's Criteria API.

静态元模型对于使用 JPA 的 Criteria API创建类型安全查询非常有用。

For example, let's have the following two entities, Orderand Item:

例如,让我们有以下两个实体,Order以及Item

@Entity
public class Order {
    @Id 
    @GeneratedValue
    Integer id;

    @ManyToOne 
    Customer customer;

    @OneToMany 
    Set<Item> items;

    BigDecimal totalCost;

    // accessors
}

and the Itementity:

Item实体:

@Entity  
public class Item { 
    @Id
    @GeneratedValue
    Integer id;

    int quantity;

    @ManyToOne
    Order order;

    // accessors
}

Here's a typesafe criteria query, build with the Criteria API:

这是一个类型安全的标准查询,使用 Criteria API 构建:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
cq.where(cb.equal(itemNode.get(Item_.id), 5)).distinct(true);

Note the usage of Item_.idand Order_.item. Those access staticallythe static meta-model properties (which mirror the entity properties) and this way it's ensuredthat the query is build properly.

注的用法Item_.idOrder_.item。那些静态访问静态元模型属性(反映实体属性),这样可以确保正确构建查询。

回答by Ellie Maynard

I've been thinking about this a lot lately as I've been trying to learn and understand JPA. I believe I have an answer to your question: Why do we need MetaModels, and why can't we just use the Entity Model?

我最近一直在思考这个问题,因为我一直在努力学习和理解 JPA。我相信我对你的问题有了答案:为什么我们需要元模型,为什么我们不能只使用实体模型?

Take a look at this entity:

看看这个实体:

@Entity  
public class Item { 
    @Id
    @GeneratedValue
    Integer id;

    int quantity;

    @ManyToOne
    Order order;

    // accessors
}

Note that none of the properties on the Entity have the keyword static. That means that in order to use them, we need to create a new Object.

请注意,实体上的所有属性都没有关键字 static。这意味着为了使用它们,我们需要创建一个新对象。

When we are building queries with CriteriaBuilder, we don't need to create an object... we just want to use the properties on the Entity to generate our query. This is the reason we have MetaModels! They create static properties that we can access without having to create an object. So we can can do things like Konstantin mentioned:

当我们使用 CriteriaBuilder 构建查询时,我们不需要创建对象……我们只想使用实体上的属性来生成我们的查询。这就是我们拥有元模型的原因!它们创建了我们无需创建对象即可访问的静态属性。所以我们可以像康斯坦丁提到的那样做:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
cq.where(cb.equal(itemNode.get(Item_.id), 5)).distinct(true);

Here, we aren't making an "Item" object... we just need to know the properties of it. The static properties on the MetaModel enable us to do so!

在这里,我们不是在制作“Item”对象……我们只需要知道它的属性。MetaModel 上的静态属性使我们能够这样做!