Запрос гибернации с вопросом о получении - PullRequest
0 голосов
/ 13 ноября 2009

У меня есть 2 сущности в отношениях один-ко-многим:

OfficeView.java:

public class OfficeView implements java.io.Serializable {

    private Integer officeId;
    private String addr1;
    private String city;
    private String state;
    private String zip;
    private List<Devices> devices;

getters and setters

    @OneToMany(mappedBy = "officeView", fetch = FetchType.EAGER)
    public List<Devices> getDevices() {
        return devices;
    }

    public void setDevices(List<Devices> devices) {
        this.devices = devices;
    }

}

Devices.java:

public class Devices implements java.io.Serializable {

    private Integer devId;
    private String devName;
    private Date lastUpdate;
    private OfficeView officeView;

getters and setters

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "office_id")
    public OfficeView getOfficeView() {
        return officeView;
    }

    public void setOfficeView(OfficeView officeView) {
        this.officeView = officeView;
    }

}

Для некоторых устройств в таблице есть 2 практически идентичные записи, кроме lastUpdate. Я всегда хочу получить самую последнюю запись в таблице. И только эта запись.

Например, у вас есть 2 записи для этого устройства:

SSA-PITTSB-PA-NEF82 2009-10-12 23:51:07 SSA-PITTSB-PA-NEF82 2009-10-15 14: 19: 35

Когда я загружаю экземпляр OfficeView для офиса, содержащего это (и другие устройства), я хочу получить только самое последнее из этих двух устройств. В базе данных я могу получить этот короткий список из таблицы устройств с помощью этого SQL-запроса:

select t.* from
  (select dev_id, dev_name, max(last_update) maxValue 
from devices
  group by dev_name) x
join devices t on x.dev_name=t.dev_name
and x.maxValue=t.last_update

SSA-PITTSB-PA-NEF82 2009-10-15 14: 19: 35

Это приложение-шов, и OfficeViewHome.java, из которого вызывается запрос, расширяет EntityHome. Я думаю, что правильный способ сделать это перегрузить loadInstance с настроенным запросом.

Я просто не знаю, как построить запрос. Как мне это сделать?

Я знаю, как написать запрос на соединение в SQL, чтобы объединить таблицы oFfice_view и devices и получить все правильные данные. Но я не могу использовать этот запрос для загрузки экземпляра (как в createNativeQuery), потому что данные из таблицы устройств должны быть загружены как список объектов Devices.

Я действительно надеюсь, что это имеет смысл, потому что я совершенно тупой.

april26

1 Ответ

0 голосов
/ 13 ноября 2009

Вам придется переопределить загрузчик коллекции - имейте в виду, что это расширение Hibernate к стандарту JPA. Вы можете использовать SQL-запрос для этого вместо написания HQL - действительно, в этом случае написание HQL может быть несколько проблематичным.

@Loader(namedQuery = "latestDevices")
@NamedNativeQuery(name="latestDevices", query="...", resultClass = Devices.class)
@OneToMany(mappedBy = "officeView", fetch = FetchType.EAGER)
public List<Devices> getDevices() {
  return devices;
}

Фактический запрос - это тот, который вы написали выше, с дополнительным условием для office_id, значение параметра которого будет предоставлено Hibernate:

select t.* from
 (select dev_id, dev_name, max(last_update) maxValue 
    from devices
   group by dev_name) x
  join devices t on x.dev_name=t.dev_name
   and x.maxValue=t.last_update
   and t.office_id = ?

Если имена не являются уникальными во всем, вам придется переписать вышеупомянутое, чтобы явно присоединить office к идентификатору для внутреннего выбора, потому что вы не можете повторить заполнитель ?.

Будьте очень осторожны с обновлением / удалением Devices через коллекцию на Office, Hibernate пытается оптимизировать определенные операции и может в конечном итоге удалить устройства для заданного Office, который не был получен выше, выберите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...