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() 返回对象数组的对象数组

hibernate executeSQLQuery 查询多个表怎么返回值

Hibernate query.list()查询结果为空

hibernate 中 query.list()的优化

Hibernate查询多个数据