我刚开始使用JPA 2标准查询API并且发现它很难学习.看了一下网络,但还没有找到好的例子/教程.有人可以建议一个很好的教程和/或帮我处理以下我想编写的简单查询吗?
我有一个名为Transaction的类,它引用了它所属的Account:
public class Transaction {
private Account account;
...
}
public class Account {
private Long id;
...
}
Run Code Online (Sandbox Code Playgroud)
我需要编写一个查询,根据帐户ID获取帐户的所有交易.这是我尝试这样做(显然不起作用):
public List<Transaction> findTransactions(Long accountId) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Transaction> query = builder.createQuery(Transaction.class);
Root<Transaction> transaction = query.from(Transaction.class);
// Don't know if I can do "account.id" here
query.where(builder.equal(transaction.get("account.id"), accountId));
return entityManager.createQuery(query).getResultList();
}
Run Code Online (Sandbox Code Playgroud)
有人能指出我正确的方向吗?
谢谢.纳雷什
JPA2.0中的CriteriaQuery提供了一种类型安全的选择方法,它非常棒.但我想知道它为什么不提供更新/删除操作?要批量更新/删除,您必须回到旧时编写容易出错的SQL或JPQL文本.IMO,更新/删除的CriteriaQuery不应该证明是困难的,因为where cause处理与select相同.
希望这将在下一版本的JPA中实现.
我正在寻找一种解决方案来“轻松”将 Hibernate Criteria 代码转换为 JPA Criteria 查询代码,而无需一对一地重写所有内容。是否可以将 Hibernate Criteria 转换为 SQL 查询,然后将其与 JPA Criteria 查询一起重用?欢迎任何其他解决方案。
更具体地说,我有一个返回 Hibernate Criteria 对象的复杂方法。我们希望仅使用 JPA,但这种方法太敏感,无法用我现在的时间进行重构。因此,最好找到一种有效的方法来“转换”此 Criteria 以供 JPA Criteria 查询重用。
从Hibernate Criteria api迁移到CriteriaQuery时,我遇到了一个抽象类的通用DAO,该抽象类在公共字段上具有一个位置,但对其ID进行选择,即使每个类的ID完全不同。
旧的投影看起来像这样
criteria.setProjection(Projections.id());
Run Code Online (Sandbox Code Playgroud)
有没有办法使用CriteriaQuery以类似的方式做到这一点?
编辑:完整标准代码
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(MyEntity.class);
detachedCriteria.add(Restrictions.in("accountID", accounts));
detachedCriteria.setProjection(Projections.id());
EntityManager em = ...;
Criteria criteria = detachedCriteria.getExecutableCriteria((Session) em.getDelegate());
List<Integer> list = criteria.list();
Run Code Online (Sandbox Code Playgroud) 我有 2 张桌子
| ID | 姓名 |
|---|---|
| 1 | 亚历克斯 |
| ID | 姓名 | 地位 | 企业ID |
|---|---|---|---|
| 7 | 苹果12 | 积极的 | 1 |
| 8 | 苹果11 | 积极的 | 1 |
| 6 | iphone13 | 禁用 | 1 |
这种关系是一对多的(一个企业有多个产品)。我想和Enterprise他们所有人Product一起得到一个条件是Status这样Product的ACTIVE
我怎样才能得到json的结果是
{
"id": "1",
"name": "Alex",
"products": [
{
"id": "7",
"name": "Iphone12",
},
{
"id": "8",
"name": "Iphone11",
}
]
}
Run Code Online (Sandbox Code Playgroud) 在使用条件查询获取列表属性时,我正在观察 JPA 2 中我认为的意外行为。
我的查询如下(摘录):
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<MainObject> c = b.createQuery(MainObject.class);
Root<MainObject> root = c.from(MainObject.class);
Join<MainObject, FirstFetch> firstFetch = (Join<MainObject, FirstFetch>) root.fetch(MainObject_.firstFetch);
firstFetch.fetch(FirstFetch_.secondFetch); //secondFetch is a list
c.select(root).distinct(true);
Run Code Online (Sandbox Code Playgroud)
(所以假设我正在获取一个列表作为对象属性的属性。)
问题是当查询返回多个结果时,secondFetch 值的重复次数与返回的行数相同。每个firstFetch应该只有一个secondFetch但有n。在这种情况下,我看到的唯一特殊之处是所有 MainObject碰巧都具有相同的 FirstFetch 实例。所以我的猜测是加入正在交叉,这是正常的,但后来JPA没有其分配secondFetch对象的每一个firstFetchs。
映射不应该太特别,或多或少是这样的
@Entity
@Table(name="mainobject")
public class MainObject{
//...
private FirstFetch firstFetch;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="mainObject_column")
public FirstFetch getFirstFetch() {
return firstFetch;
}
}
Run Code Online (Sandbox Code Playgroud)
和
@Entity
@Table(name="firstFetch")
public class FirstFetch{
//...
private List<SecondFetch> secondFetch;
@OneToMany(mappedBy="secondFetch") …Run Code Online (Sandbox Code Playgroud) 假设我在Oracle DB中有一列是这样的:
SOMETHING_TS TIMESTAMP WITH TIME ZONE
我想使用CriteriaQuery按此列进行过滤。
我可以使用本机查询来实现此目的:
SELECT *
FROM SOMETHING
WHERE TRUNC(SOMETHING_TS) = TO_DATE('2016-12-08','YYYY-MM-DD');
Run Code Online (Sandbox Code Playgroud)
但是在Java中我没有这样做,下面是我的示例代码:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyClass> cq = cb.createQuery(MyClass.class);
Date date = new Date();
predicates.add(cb.equal(cb.function("TRUNC", Date.class, myClass.get("somethingTs")), cb.function("TO_DATE", Date.class, cb.parameter(Date.class, "somethingTs"), cb.literal("YYYY-MM-DD"))));
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
TypedQuery<MyClass> query = em.createQuery(cq);
query.setParameter("somethingDt", date);
Run Code Online (Sandbox Code Playgroud) 如何在 Spring JPA 规范中构建以下 SQL 查询?
SELECT col1, col2, MAX(col3)
FROM table_name t1
WHERE col4 IN (1,2,3) AND status IN ('STATUS_1','STATUS_2') AND
NOT EXISTS
(
SELECT 1 FROM table_name t2 WHERE t1.id = t2.parent_id
AND t2.status IN ('STATUS_3','STATUS_4')
)
GROUP BY col1, col2;
Run Code Online (Sandbox Code Playgroud)
爪哇代码:
return new Specification<TableEntity>() {
@Override
public Predicate toPredicate(Root<TableEntity> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
// how to build Predicates for the above query which has self-join and not exists.
}
};
Run Code Online (Sandbox Code Playgroud) 给定
@Entity
public class Document {
@Id
@Column(name = "DOCUMENT_ID")
private Long id;
@ElementCollection
@CollectionTable(
name="TAG",
joinColumns=@JoinColumn(name="DOCUMENT_ID")
)
@Column(name="TAG")
private Set<String> tags;
}
Run Code Online (Sandbox Code Playgroud)
查找带有特定标签集合的所有文档。本质上,EclipseLink 相当于:
SELECT d FROM Document d WHERE :tag1 MEMBER OF d.tags
INTERSECT
SELECT d FROM Document d WHERE :tag2 MEMBER OF d.tags
...
SELECT d FROM Document d WHERE :tagn MEMBER OF d.tags
Run Code Online (Sandbox Code Playgroud)
但使用 JPA CritieraQuery。
我正在使用 jhipster 标准和 jpa 规范来实现用于研究的端点。
好吧,它正在工作,但继续向我发送重复项。
有这个模型的prestations
public class Prestation extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@NotNull
@Column(name = "jhi_label", nullable = false)
private String label;
@Column(name = "description")
private String description;
@Column(name = "unit")
private String unit;
@NotNull
@Column(name = "activated", nullable = false)
private boolean activated;
@ManyToOne(optional = false)
@NotNull
@JsonIgnoreProperties("prestations")
private SubCategory subCategory;
@OneToMany(mappedBy = "prestation", cascade = …Run Code Online (Sandbox Code Playgroud)