Hibernate Query.list 返回实际的 Object 实例而不是预期的类型
Posted
技术标签:
【中文标题】Hibernate Query.list 返回实际的 Object 实例而不是预期的类型【英文标题】:Hibernate Query.list returns actual Object instance instead of expected type 【发布时间】:2013-08-15 18:17:32 【问题描述】:当使用连接在 HQL 中执行休眠查询并随后调用 query.list
以返回匹配对象的列表时,我最终得到的是实际对象实例(即 query.list().get(0).getClass() == Object.getClass()
)的列表,而不是预期的实例对象。
在没有连接的情况下运行查询会正确返回预期类型的对象,并且可以正确地转换和使用它们。
到目前为止,我的搜索还没有发现任何可能导致此问题的原因。在 hql 中使用 join 以确保正确映射对象时,我还需要做些什么吗?
编辑:在下面添加了代码摘录。我不得不更改所有名称并尝试仅提取相关部分(真正的代码与汽车无关)。
工作查询:
from Car car where car.name like :name
非工作查询:
from Car car left join car.occupants occupant where car.name like :name OR (occupant.name like :oname)
汽车实体:
@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = "someId"),
@UniqueConstraint(columnNames = "someOtherId"))
public class Car extends SomeParentEntity
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 64)
private String someId;
@Column(length = 64)
private String name;
// ... Many columns and mappings removed ...
@OneToMany(mappedBy = "car", fetch = FetchType.LAZY)
private List<Occupant> occupants;
// ...
居住者实体:
@Entity(name = "car.Occupant")
@Table(uniqueConstraints = @UniqueConstraint(columnNames = "name" ) )
public class User extends SomeParentEntity
@ManyToOne
@JoinColumn(name = "carId", nullable = false)
private Car car;
@Column(length = 64, nullable = false)
private String name;
// ... Many mappings / columns removed ...
【问题讨论】:
请出示您的代码 @MikeQ 添加了代码摘录。 【参考方案1】:您在 HQL 中的 JOIN
正在让 Hibernate 检索两种类型的对象。如果您激活 SQL 日志记录,您可以看到这一点。
假设您的实体中有 X-to-X 关系,如果您将查询更改为使用,问题应该会消失
... JOIN FETCH entity.relation ...
【讨论】:
谢谢你的建议,但我不确定它是否会起作用。我相信,如果您使用join fetch
,我的理解是您不能(或不应该?)在 where 子句中使用连接的实体。加入的原因(在原始问题中未说明,抱歉)专门用于使用 where 子句进行选择,所以我不相信我可以在这种情况下使用 fetch 。为了更清楚,我在问题中添加了一些代码摘录。
@increment1 JOIN FETCH
只是意味着 Hibernate 将使用连接而不是单独的选择来获取您的第二个对象。以现在的方式,您实际上并没有“加入”(如将一个对象设置为另一个对象)。
+1 的建议,但不幸的是这对我不起作用,因为它导致了一个抱怨所有权的查询异常。【参考方案2】:
顺便说一句,你为什么要使用显式左连接。
from Car car left join car.occupants occupant where car.name like :name OR (occupant.name like :oname)
我认为我们可以简单地使用:
from Car car where car.name like :name or car.occupant.name like :oname
那么 query.list 应该为您提供对象列表,该对象应该被转换回汽车列表
【讨论】:
+1 虽然我不确定您是否可以参考 car.occupant,因为该字段是 car.occupants ,这是一个列表。我不确定您是否可以按照您所写的方式进行隐式映射。我还没有测试过,因为我在尝试之前找到了另一个解决方案。【参考方案3】:+1 向其他回答者寻求帮助,非常感谢。
但是,结果证明解决方案非常简单。查询只需要在连接案例的开头指定选择以缩小字段范围(我假设)。
所以不工作的查询:
from Car car left join car.occupants occupant where car.name like :name OR (occupant.name like :oname)
变成:
select car from Car car left join car.occupants occupant where car.name like :name OR (occupant.name like :oname)
【讨论】:
我一直在到处寻找这个解决方案。如此简单,这解决了我的问题。以上是关于Hibernate Query.list 返回实际的 Object 实例而不是预期的类型的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate query.list() 方法返回空列表而不是空值
Hibernate HQL - query.list() 返回对象数组的对象数组