Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Оператор case HQL, возвращающий объект сущности

Автор вопроса: JardoОтветов: 1

У меня есть таблица записей (для простоты я опустил сеттеры и другие атрибуты):

@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. Как это сделать?

hibernatecasehql

Ответы

Ответ 1 · Mikko Maunu

Такой запрос JPQL/HQL можно написать без выбора регистра:

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 не требуется.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы