我现在试图弄清楚这段代码大约两个小时,例如在下面的类中这些字段代表什么?
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;
}
Address.class
是一个java类,它具有以下定义:
@Entity
@Table(name = "address", schema = "public")
public class Address{
private Long id;
private Person person;
private UUID personId;
//....
}
请您解释一下用于@StaticMetamodel
和@SingularAttribute
注释的内容是什么?这可能很简单,但我无法理解。
答案 0 :(得分:19)
静态元模型是一系列“镜像”实体的类 和嵌入在域模型中并提供静态访问 有关镜像类属性的元数据。
静态元模型具有以下属性:
X
中的每个托管类p
,都会创建包X_
中的元模型类p
。y
声明的每个持久性非集合值属性X
,其中y
的类型为Y
,元模型类必须包含声明为如下: SingularAttribute
示例:
public static volatile SingularAttribute<X, Y> y;
静态元模型对于使用JPA的Criteria API创建类型安全查询非常有用。
例如,让我们拥有以下两个实体,Order
和Item
:
@Entity
public class Order {
@Id
@GeneratedValue
Integer id;
@ManyToOne
Customer customer;
@OneToMany
Set<Item> items;
BigDecimal totalCost;
// accessors
}
和Item
实体:
@Entity
public class Item {
@Id
@GeneratedValue
Integer id;
int quantity;
@ManyToOne
Order order;
// accessors
}
这是一个使用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);
请注意Item_.id
和Order_.item
的使用情况。那些访问静态静态元模型属性(镜像实体属性),这样确保查询构建正确。
答案 1 :(得分:3)
最近,在尝试学习和理解JPA时,我一直在思考很多。我相信我对您的问题有一个答案:为什么我们需要元模型,为什么我们不能仅使用实体模型?
看看这个实体:
@Entity
public class Item {
@Id
@GeneratedValue
Integer id;
int quantity;
@ManyToOne
Order order;
// accessors
}
请注意,实体上的所有属性都没有关键字static。这意味着要使用它们,我们需要创建一个新的对象。
当我们使用CriteriaBuilder构建查询时,我们不需要创建对象……我们只想使用Entity上的属性来生成查询。这就是我们拥有元模型的原因!它们创建了无需创建对象即可访问的静态属性。这样我们就可以做类似Konstantin的事情:
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);
在这里,我们不是在创建“ Item”对象……我们只需要知道它的属性即可。 MetaModel的静态属性使我们能够这样做!