gpt4 book ai didi

api - ElementCollection 与 JPQL 方法上的 CriteriaBuilder.isEmpty

转载 作者:行者123 更新时间:2023-12-05 05:28:54 24 4
gpt4 key购买 nike

我正在尝试使用 JPA2 标准 API 对以下类进行简单查询:

// a lot of imports

@Entity
public class Thing {
enum Type { FIRST, SECOND, THIRD };

@SequenceGenerator(name = "Thing_SeqGen", sequenceName = "Thing_Id_Seq", initialValue = 1000)
@Id
@GeneratedValue(generator = "Thing_SeqGen")
private int id;

private String name = "name";

@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Thing.Type.class)
@CollectionTable(name = "TYPES", joinColumns = { @JoinColumn(referencedColumnName = "ID", name = "TYPE_ID") })

private Set<Thing.Type> typeSet = new HashSet<Thing.Type>();
public static void main(final String[] args) {
new Thing().start();
}

public void start() {
final Thing firstThing = new Thing();
firstThing.setName("First one");
firstThing.setTypeSet(EnumSet.of(Thing.Type.FIRST));
final Thing firstAndSecondThing = new Thing();
firstAndSecondThing.setName("Test2");
firstAndSecondThing.setTypeSet(EnumSet.of(Thing.Type.FIRST, Thing.Type.SECOND));
final Thing bareThing = new Thing();
bareThing.setName("Test3");

final EntityManagerFactory emf = Persistence.createEntityManagerFactory("sandbox");
final EntityManager em = emf.createEntityManager();

em.getTransaction().begin();
em.persist(firstThing);
em.persist(firstAndSecondThing);
em.persist(bareThing);
em.getTransaction().commit();

em.getTransaction().begin();
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Thing> c = cb.createQuery(Thing.class);
final Root<Thing> root = c.from(Thing.class);
final Join<Thing, Set<Thing.Type>> typeJoin = root.join("typeSet");

c.select(root).distinct(true).where(cb.isEmpty(typeJoin));

final List<Thing> results = em.createQuery(c).getResultList();

em.getTransaction().commit();
}

// getter/setter methods omitted
}

我要查询的是:查找所有没有排版的东西。

完成这项工作的 JPQL 是:

从 t.typeSet 为空的 Thing t 中选择 t

JPQL 查询返回一个预期的结果。条件查询不返回任何结果。 CriteriaBuilder 创建:

SELECT DISTINCT t0.ID, t0.NAME FROM THING t0, TYPES t1 WHERE (((SELECT COUNT(t2.ID) FROM THING t2 WHERE (t1.TYPE_ID = t0.ID)) = 0) * *AND (t1.TYPE_ID = t0.ID)**)

最后的 theta-join(标记为 **)将全部杀死。而且我不知道为什么表 THING 被指定两次 (THING to, THING t1)

显然我做错了。但我不知道出了什么问题。

最佳答案

我猜问题是您正试图在 Criteria 案例中进行显式联接,而在 JPQL 中您没有这样做。所以省略连接并做类似的事情

Metamodel model = emf.getMetamodel();
ManagedType thingType = model.managedType(Thing.class);
CollectionAttribute typeSetAttr = thingType.getCollection("typeSet");
c.select(root).distinct(true).where(cb.isEmpty(root.get(typeSetAttr)));

然后这应该转换为与您发布的相同的 JPQL ...或者至少它适用于 DataNucleus JPA 实现。

关于api - ElementCollection 与 JPQL 方法上的 CriteriaBuilder.isEmpty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6340554/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com