【问题标题】:HQL case statement returning entity objectHQL case语句返回实体对象
【发布时间】:2013-10-25 08:45:12
【问题描述】:

我有一个记录表(为简单起见,我省略了 setter 和其他属性):

@Entity  
@Table(name="RECORD")  
public class Record {

    private long id;

    @Id
    @GeneratedValue
    @Column(name="ID") 
    public long getId() {
        return id;
    }
}

还有一个记录冲突表:

@Entity
@Table(name = "RECORD_COLLISION")
public class RecordCollision {

    private long id;

    private Record firstRecord;

    private Record secondRecord;

    @Id
    @GeneratedValue
    @Column(name = "ID")
    public long getId() {
        return id;
    }

    @ManyToOne()
    @JoinColumn(name = "FIRST_RECORD")
    public Record getFirstRecord() {
        return firstRecord;
    }

    @ManyToOne()
    @JoinColumn(name = "SECOND_RECORD")
    public Record getSecondRecord() {
        return secondRecord;
    }
}

我需要选择所有与指定记录发生冲突的记录。我尝试使用这个 HQL 查询:

SELECT CASE WHEN rc.firstRecord = :record THEN rc.secondRecord ELSE rc.firstRecord END 
    FROM RecordCollision rc 
    WHERE rc.firstRecord = :record OR rc.secondRecord = :record

我需要使用CASE语句,因为指定的记录可以在firstRecord列中,这种情况我需要返回secondRecord,反之亦然。

问题是,在执行 query.list() 之后,我没有得到 Record 实例的列表,而是包含一个 Object 实例的列表。似乎 Hibernate 不知道它应该将 CASE 语句的结果作为 Record 的实例返回。这应该怎么做?

【问题讨论】:

    标签: hibernate hql case


    【解决方案1】:

    这样的 JPQL/HQL 查询可以在没有 select-case 的情况下编写:

    SELECT DISTINCT(r) FROM Record r 
    WHERE 
    r.id in (SELECT rc1.firstRecord.id 
             FROM RecordCollision rc1 
             WHERE rc1.secondRecord = :record) 
    OR 
    r.id in (SELECT rc2.secondRecord.id 
             FROM RecordCollision rc2 
             WHERE rc2.firstRecord = :record)
    

    如果一个冲突仅由一行呈现,则不需要DISTINCT

    【讨论】:

    • 感谢您的替代方案,但执行 2 个子选择是否效率太低?
    • 性能取决于例如数据库的查询优化器和数据量。通常情况下,如果不进行衡量,就不可能说效率太低了。
    • 它的表现是否足够好,还是您最终找到了其他解决方案?
    • 在写这个问题时,我已经有了一个临时解决方案,使用两个单独的查询并合并结果。这种“临时”解决方案最终投入生产,至今仍在使用(很可能不会再改变)。现在我有一个类似的问题(这就是我回到这个问题的原因),我将使用你的解决方案。虽然我认为它不是很有效,但它仍然可能比执行两个单独的查询更好。
    猜你喜欢
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 2022-10-13
    • 2021-09-13
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多