在Sun Online资源中,他们提供了关于Criteria/Metamodel API使用的儿子示例,但据我了解Java,似乎无法工作:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class);
EntityType<Owner> Owner_ = m.entity(Owner.class);
Root<Pet> pet = cq.from(Pet.class);
Join<Owner, Address> address = cq.join(**Pet_.owners**).join(**Owner_.addresses**);
Run Code Online (Sandbox Code Playgroud)
Pet_是一个类的实例, EntityType它没有定义任何名为owners或的属性addresses.
他们确实定义了名为Pet_和Owner_元模型的类,但是在这里输入它们会产生与变量名称的冲突......我是对的吗?
__
(这个问题也与此相关的一个)
我想知道在条件查询期间是否可以初始化实体的瞬态属性.
例
@Entity
public SampleEntity{
@Id
private long id;
[more attributes]
@Transient
private String someTransientString;
[getters and setters]
}
Run Code Online (Sandbox Code Playgroud)
现在我想编写一个CriteriaQuery来加载所有SampleEntitys并自动设置someTransientString为imamightlyfinestring.我有类似以下SQL的内容:
SELECT ID AS ID, [..], 'imamightilyfinestring' AS SOME_TRANSIENT_STRING FROM SAMPLE_ENTITY
Run Code Online (Sandbox Code Playgroud)
我当然知道我可以简单地迭代生成的集合并手动设置属性,但我想知道是否有办法在JPA2中完成它.
谢谢 :)
我似乎错过了JPA的标准API及其类型安全性.请考虑以下代码:
@Entity
@Access(FIELD)
class User(
@Id
Long id;
@Column(unique=true)
String email;
String password;
}
Run Code Online (Sandbox Code Playgroud)
元模型在这里:
@StaticMetamodel(User.class)
public static class User_ {
public static volatile SingularAttribute<User, Long> id;
public static volatile SingularAttribute<User, String> email;
public static volatile SingularAttribute<User, String> password;
}
Run Code Online (Sandbox Code Playgroud)
然后使用Java EE教程中的页面构建一些代码来运用该类:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> user = cq.from(User.class);
cq.select(user);
cq.where(cb.equal(user.get(User_.email), "john@google.com")); //this line is my problem
TypedQuery<User> q = em.createQuery(cq);
List<User> allUsers = q.getResultList();
assertEquals(1, allUsers.size());
Run Code Online (Sandbox Code Playgroud)
它工作正常.但是,如果我更改"where"子句以使用Integer而不是String("john@google.com"),我希望代码不能编译.然而它汇编得很好.
我认为标准API应该是类型安全的吗?使用标准JPQL,这几乎不比以下更安全.我的意思是,上面代码中元模型的目的是什么?我从中获得了一切.
User u = em.createQuery("select …Run Code Online (Sandbox Code Playgroud) 我想执行一个匹配特定子类属性的查询,所以我正在尝试使用treat().
在这个例子中我想要:
名称以"a"开头的
所有科目,或所有科目,即姓名以"a"开头的人
private List<Subject> q1()
{
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<Subject> q = b.createQuery(Subject.class);
Root<Subject> r = q.from(Subject.class);
q.select(r);
q.distinct(true);
q.where(
b.or(
b.like(r.get(Subject_.name), "a%"),
b.like(b.treat(r, Person.class).get(Person_.lastName), "a%")));
return em.createQuery(q).getResultList();
}
Run Code Online (Sandbox Code Playgroud)
显然,Person扩展Subject,Subject是抽象的,继承是SINGLE_TABLE,并 (非进水).Subject有@DiscriminatorOptions(force = true)其他原因
但生成的SQL是这样的:
select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_
where subject0_.DTYPE='Person' and (subject0_.name like 'a%' or subject0_.lastName like 'a%')
Run Code Online (Sandbox Code Playgroud)
虽然我期待:
select distinct subject0_.ID as ID2_71_, …Run Code Online (Sandbox Code Playgroud) 我有一个使用JOIN和ORDER BY的查询,并希望使用Criteria Api在我的存储库中使用它.
在这里,我发现,如何将这样的查询包装到CriteriaQuery(链接)中.
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
Join<Pet, Owner> owner = cq.join(Pet_.owners);
cq.select(pet);
cq.orderBy(cb.asc(owner.get(Owner_.lastName),owner.get(Owner_.firstName)));
Run Code Online (Sandbox Code Playgroud)
另一方面,我发现了一些使用Criteria Api和JpaRepository(示例)的示例.
问题是存储库中的所有方法都需要一个规范:
T findOne(Specification<T> spec);
Run Code Online (Sandbox Code Playgroud)
总是像这样构建:
public static Specification<PerfTest> statusSetEqual(final Status... statuses) {
return new Specification<PerfTest>() {
@Override
public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.not(root.get("status").in((Object[]) statuses));
}
};
}
Run Code Online (Sandbox Code Playgroud)
所以在一方面我知道如何创建CriteriaQuery,另一方面我需要一个从Predicate构建的规范,我无法弄清楚如何将CriteriaQuery解析为Specification/Predicate.
我有一个班级Customer和CustomerDependant实体.Customer与其家属有多对多的双向关系.我需要找到按名称和从属名称过滤的客户.
它在JPQL中做了类似的事情:
select c join fetch c.dependants d from Customer c where c.name like
'foo' and d.name like 'foo'
Run Code Online (Sandbox Code Playgroud)
我如何使用JPA Criteria Queries做同样的事情?
我想将我的JPAQL查询转换为条件API查询.
考虑这样的查询:
SELECT e FROM Entity e WHERE e.parent.id = :parentId
Run Code Online (Sandbox Code Playgroud)
WHERE 部分转换为:
Path<Long> parentId = root.get(Entity_.parent).get(ParentEntity_.id);
Predicate whereParentId = builder.equal(parentId, selectedParent.getId());
Run Code Online (Sandbox Code Playgroud)
问题是,如何为WHERE创建谓词,如下所示:
SELECT e FROM Entity e WHERE e.parent.parent.id = :parentId
Run Code Online (Sandbox Code Playgroud)
如何创建Path父ID的父级?
我正在使用Hibernate保护我的网站免受SQL注入.
我听说Hibernate Criteria API比HQL更强大.Hibernate Criteria Api是否完全防止SQL注入?
java hibernate sql-injection criteria-api hibernate-criteria
我正在使用JPA Criteria API构建查询.当我使用javax.persistence.criteria.Path#in(Collection<?>)方法创建两个限制谓词时,生成的SQL查询与我所考虑的有点不同.
构建在int属性上的第一个谓词产生了SQL,内联参数集合的所有元素:in (10, 20, 30).
构建在String属性上的第二个谓词产生了参数化的SQL : in (?, ?, ?).
让我展示:
实体:
@Entity
public class A {
@Id
private Integer id;
private int intAttr;
private String stringAttr;
//getter/setters
}
Run Code Online (Sandbox Code Playgroud)
查询:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<A> q = cb.createQuery(A.class);
Root<A> root = q.from(A.class);
q.where(
root.get("intAttr").in(Arrays.asList(10, 20, 30)),
root.get("stringAttr").in(Arrays.asList("a", "b", "c"))
);
entityManager.createQuery(q).getResultList();
Run Code Online (Sandbox Code Playgroud)
日志:
select
a0_.id as id1_0_,
a0_.intAttr as intAttr2_0_,
a0_.stringAttr as stringAt3_0_
from
A a0_
where
(
a0_.intAttr …Run Code Online (Sandbox Code Playgroud) 我有以下型号:
@Entity
@Table(name = "SAMPLE_TABLE")
@Audited
public class SampleModel implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "NAME", nullable = false)
@NotEmpty
private String name;
@Column(name = "SHORT_NAME", nullable = true)
private String shortName;
@ManyToOne(fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "MENTOR_ID")
private User mentor;
//other fields here
//omitted getters/setters
}
Run Code Online (Sandbox Code Playgroud)
现在我只想查询列:id、name、shortName和mentor引用User实体(不是完整的实体,因为它有许多其他属性,我希望获得最佳性能)。
当我写查询时:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<SampleModel> query = builder.createQuery(SampleModel.class);
Root<SampleModel> …Run Code Online (Sandbox Code Playgroud) criteria-api ×10
java ×8
jpa ×6
hibernate ×4
jpa-2.0 ×4
criteria ×1
inheritance ×1
metamodel ×1
mysql ×1
type-safety ×1