关于Hibernate查询的一组问题
请帮助我解决这些 Hibernate 查询问题。
考虑以下结构:
@Entity
class Manager {
@OneToMany
List<Project> projects;
}
0) HQL 中有 2 种可能的动态获取方式:
- select m from Manager m join m.projects
- from Manager m join fetch m.projects
中我的设置第二个总是返回列表中对象数量错误的笛卡尔积结果,而第一个总是返回列表中实体数量正确的结果。但 sql 查询看起来是一样的。这是否意味着“select”子句从内存列表中删除冗余对象?在这种情况下,在书中看到使用 select unique ... 来消除冗余实体的建议很奇怪,而“select”则完成了这项工作。如果这是一个错误的假设,那么为什么这两个查询返回不同的结果?
如果我通过上述 2 种方法之一使用动态获取,我会在休眠 SQL 日志中看到经典的 n+1 选择问题输出。事实上,FetchMode 注释(子选择或连接)在动态获取时没有任何功能。在这种特殊情况下,我真的无法解决 n+1 问题吗?
看起来 Hibernate Criteria API 不支持泛型。我说得对吗?看起来我必须改用 JPA Criteria API?
是否可以编写包含实体名称参数的 HQL 查询?例如“from :myEntityParam p where p.id=1”并在此之后调用 setParameter("myEntityParam", MyClass.class) 。实际上我想要的是通用的 HQL 查询,用一个通用的 dao 替换多个非通用的 dao。
Please help me with these Hibernate querying issues.
Consider the following structure:
@Entity
class Manager {
@OneToMany
List<Project> projects;
}
0) there are 2 possible ways of dynamic fetching in HQL:
- select m from Manager m join m.projects
- from Manager m join fetch m.projects
In my setup second one always returns a result of cartesian product with wrong number of objects in a list, while the first one always returns correct number of entities in a list. But the sql queries look the same. Does this mean that "select" clause removes redundant objects from the list in-memory? In this case its strange to see an advice in a book to use select distinct ... to get rid of redundant entities, while "select" does the job. If this is a wrong assumption than why these 2 queries return different results?
If I utilize dynamic fetching by one of the 2 methods above I see a classic n+1 select problem output in my hibernate SQL log. Indeed, FetchMode annotations (subselect or join) do not have power while fetching dynamically. Do I really can't solve the n+1 problem in this particular case?
Looks like Hibernate Criteria API does not support generics. Am I right? Looks like I have to use JPA Criteria API instead?
Is it possible to write HQL query with an entity name parameter inside? For example "from :myEntityParam p where p.id=1" and call setParameter("myEntityParam", MyClass.class) after this. Actually what I want is generic HQL query to replace multiple non-generic dao's by one generic one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
0) 我总是使用 select 子句,因为它允许告诉您要选择的内容,并且无论如何在 JPQL 中都是强制的。如果您想选择经理及其项目,请使用
如果您不使用distinct关键字,则列表将包含每个经理的n个实例(n是经理的项目数):Hibernate返回与那里一样多的元素是结果集中的行。
1) 如果要避免 n + 1 问题,请在同一查询中获取其他关联:
您还可以配置批量获取,以在访问第一个 boss 时一次加载 10 个 boss(例如)。在参考文档中搜索“批量获取”。
2)整个Hibernate API没有被泛化。它是在 JDK 1.4 上创建的,早于泛型。这并不意味着它没有用。
3) 不。HQL 查询参数归根结底是准备好的语句参数。您必须使用字符串连接来执行此操作。
0) I always use a select clause, because it allows telling what you want to select, and is mandatory in JPQL anyway. If you want to select the managers with their projects, use
If you don't use the distinct keyword, the list will contain n instances of each manager (n being the number of projects of the manager): Hibernate returns as many elements as there are rows in the result set.
1) If you want to avoid the n + 1 problem, fetch the other association in the same query:
You may also configure batch fetching to load 10 bosses (for example) at a time when the first boss is accessed. Search for "batch fetching" in the reference doc.
2) The whole Hibernate API is not generified. It's been made on JDK 1.4, before generics. That doesn't mean it isn't useful.
3) No. HQL query parameters are, in the end, prepared statement parameters. You must use String concatenation to do this.