JPQL新对象实例化

时间:2012-07-11 08:15:07

标签: java java-ee jpa eclipselink jpql

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

命名查询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被执行时,它既不会打印出“在构造函数2”的语句,也不会返回结果。

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

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

提前致谢。

1 个答案:

答案 0 :(得分: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大小。