java - @ManyToMany 关系中表的 JPA 2.0 CriteriaQuery

标签 java database jpa criteria jpa-2.0

我在 @ManyToMany 关系中有两个实体。

// Output has 4 other @ManyToOne relationships if that matters    
@Entity @Table public class Output {
    @Id public String address;
    @ManyToMany(targetEntity = Interval.class,
                cascade = CascadeType.ALL,
                fetch = FetchType.LAZY)
    @JoinTable(name = "output_has_interval",
               joinColumns = {@JoinColumn(name = "output_address", 
                                          referencedColumnName = "address")},
        inverseJoinColumns = {@JoinColumn(name = "interval_start",
                                          referencedColumnName = "start"),
                              @JoinColumn(name = "interval_end", 
                                          referencedColumnName = "end")})
    Collection<Interval> intervals;

@IdClass(IntervalPK.class) // I'll omit this one.
@Entity @Table public class Interval {
    @Id public Calendar start;
    @Id public Calendar start;
    @ManyToMany(targetEntity = Output.class,
                mappedBy = "intervals",
                cascade = CascadeType.ALL,
                fetch = FetchType.LAZY)
    public Collection<Output> outputs;

outputinterval 之间的连接表称为 output_has_interval

如何像这样执行 CriteriaQuery

SELECT `output`.`address`
FROM   `output`, `output_has_interval`, `interval`
WHERE  `output`.`address` = `output_has_interval`.`output_address`
AND    `interval`.`start` = `output_has_interval`.`interval_start`
AND    `interval`.`end` = `output_has_interval`.`interval_end`
AND    `interval`.`start` >= '2011-04-30'

如果我在 MySQL 中发布它,这将按预期工作。

(我也有相应的静态元模型类,根据要求我可以发布它们——没什么特别的。)

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Output> cq = cb.createQuery(Output.class);
Root<Output> root= cq.from(Output.class);
CollectionJoin<Output, Interval> join = root.join(Output_.intervals);
Expression<Calendar> start = join.get(Interval_.start);
Predicate pred = cb.greaterThanOrEqualTo(start, /* calendar for '2011-04-30' */);
cq.where(pred);
TypedQuery<Output> tq = em.createQuery(cq);

但是 tq.getResultList 从我的数据库中返回每个 output 行。有什么想法吗?

(附带说明:当我发出此查询时,Hibernate(我正在使用的提供程序)会生成许多 select 语句,每个关系都有一个 Output,有时更多。)

编辑:我写道:

tq.getResultList returns every output row from my database

澄清一下:它返回的不仅仅是我数据库中的每个 output 行。它实际上使用 outputinterval 进行连接,但是谓词:

`interval`.`start` >= '2011-04-30'

不满意。

最佳答案

好的,我会设法自己解决我的谜题。

首先:整个问题源于我是一个糟糕的程序员这一事实。我迭代了 TypedQuery<Output>.getResultList()并访问每个 IntervalOutput.intervals以递归方式,因此 Hiberate 延迟加载请求的对象,生成少量 select声明。

但是我必须得到那些 Interval以某种方式实例化。以下更改为我的CriteriaQuery成功了。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery(); // or createQuery(Tuple.class)
Root<Output> root= cq.from(Output.class); // from clause
CollectionJoin<Output, Interval> join = root.join(Output_.intervals);
Path<String> addressPath = root.get(Output_.address); // mind these Path objects
Path<Calendar> startPath = join.get(Interval_.start); // these are the key to success!
cq.multiselect(addressPath, startPath); // select clause
Expression<Calendar> start = join.get(Interval_.start);
Predicate pred = cb.greaterThanOrEqualTo(start, /* calendar for '2011-04-30' */);
cq.where(pred); // where clause
TypedQuery<Tuple> tq = em.createQuery(cq); // holds Tuples
for (Tuple tuple : tq.getResultsList()) {
    String address = tuple.get(addressPath);
    Calendar start = tuple.get(startPath);
...

编辑

我刚刚意识到我可以使用 Path<T>对象而不是 Expression<T>对象(反之亦然)为 Path<T>延伸Expression<T> .好吧……

关于java - @ManyToMany 关系中表的 JPA 2.0 CriteriaQuery,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5635287/

相关文章:

database - 如何找到数据点最多的一小时?

mysql - 如何在 mysql 中拆分/反透视 group_concat?

java - Hibernate 5.2 中的示例查询

java - 更改代码时 Maven 出现问题?

java - Spring-MVC/JPA。从数据库中提取数据后没有结果

java - 将字符串变量转换为字符

Java解析 "Thu Jun 09 2016 00:00:00 GMT+0200 (CEST)"

java - 为什么InetAddress.getLocalHost().getHostAddress()在android中返回127.0.0.1。但在JAVA程序中工作正常

java - 无法启动 springboot-admin :java. lang.NoClassDefFoundError: org/springframework/cloud/netflix/zuul/ZuulServerAutoConfiguration

php - 如何在 mysql 中查找 Sage 50 Database v22 中的关系(已转换为 mysql)