3

我有两个命名查询,并且都有相同的逻辑,除了每个都使用不同的对象构造函数将结果选择到

命名查询 1:

SELECT DISTINCT NEW dk.NewsRoomView(n,p)
FROM NewsItem n LEFT JOIN n.placements p JOIN n.actors a

命名查询 2:

SELECT DISTINCT NEW dk.NewsRoomView(n.id,n.title,SIZE(n.attachments),p.id,p.page)
FROM NewsItem n LEFT JOIN n.placements p JOIN n.actors a

NewsRoomView 类的结构

public class NewsRoomView{

  public NewsRoomView(NewsItem n, NewsItemPlacement p)
    Logger.getLogger(NewsRoomView.class.getName()).log(Level.INFO,"at Contsructor 1");
  }

  public NewsRoomView(Long id, String title, Integer attachments, Long pId, Integer page){
    Logger.getLogger(NewsRoomView.class.getName()).log(Level.INFO,"at Contsructor 2");
  }
}

现在,每当执行命名查询 1 时,它都会成功打印“at constructor 1”语句,因此查询会返回结果,但是当执行命名查询 2 时,它既不会打印出语句“at Constructor 2”,也不会返回结果。

上面的代码块只是我真正拥有的片段。实际上,第二个构造函数有一个 23 长的参数列表,它表示 NewsItem 和 NewsItemPlacement 实体中的更多字段。

我想知道阻止第二个构造函数返回结果的可能是什么错误,以及构造函数的参数列表的大小是否有限制。

提前致谢。

4

1 回答 1

3

因为没有抛出异常,这意味着生成的查询对数据库执行没有问题,但查询没有返回任何行。问题与构造函数表达式和参数数量无关。

我想附件表中没有这样的 NewsItem 条目。这样的行不会成为结果集的一部分,因为 SIZE(n.attachments) 会导致基于 id 的内部连接到附件表。如果您查看生成的 SQL 查询,这一切都会变得更加清晰。

具有相同问题的最小示例

实体

@Entity
public class EntityA {
    @GeneratedValue (strategy = GenerationType.TABLE)
    @Id public int id;
    @OneToMany(mappedBy = "a")
    public List<EntityB> bList;
     ...
}

@Entity
public class EntityB {
    @GeneratedValue (strategy = GenerationType.TABLE)
    @Id
    public int id;

    @ManyToOne
    private EntityA a;
}

数据库内容

EntityA
|ID | 
| 1 |
| 2 |

EntityB
|ID |A_ID |
| 1 |  2  |

询问

Query q = em.createQuery("Select SIZE(a.bList) FROM EntityA a");

带有 MySQL 的 EclipseLink (2.3.2) 生成以下 SQL 查询:

SELECT COUNT(t0.ID) FROM ENTITYB t0, ENTITYA t1 
WHERE (t0.A_ID = t1.ID) GROUP BY t1.ID

如您所见,它只为在 EntityB 表中具有一个或多个条目的 EntityA 返回 bList 的大小。

于 2012-07-11T09:57:51.290 回答