Hibernate - TypedQuery.getResultList () возвращает список того же объекта - PullRequest
6 голосов
/ 18 марта 2011

Вот более и, возможно, лучшее описание проблемы:

Я делаю простой запрос выбора.Возвращаемый список содержит точное количество записей / объектов, как будто я делаю один и тот же запрос в БД, но проблема в том, что все объекты одинаковы / идентичны.

Например, это результат вБД (я удалил нулевые значения):
26801 01-JAN-00 7 31-DEC-99 7 Obere Kirchstr.26 CH 8304 Walliselln
26801 01-JAN-00 2 31-DEC-99 2 Obere Kirchstr.26 CH 8304 Walliselln

И это содержимое адресов переменных, которые я вижу в Eclipse во время отладки после выполнения запроса:

address ArrayList (id = 81)
элемент elementData [10] (id = 86)
[0] DLDBAddress (id = 82)
[1] DLDBAddress (id = 82)
[2] null
...
modCount 1
размер 2

DLDBAddress [persid = 26801, valPeriodStart = 1900-01-01, valPeriodEnd = 9999-12-31, addressNr = 7, addressType = 7, addressRow1 = null, addressRow2= Обере Кирхстр.26, addressRow3 = ноль, страна = CH, postalCode = 8304, город = Walliselln, phoneNr = ноль, faxNr = ноль, секретныйPhoneNr = ноль, alternatPhoneNr = ноль, pagerNr = ноль]

DLDBAddress [persid = 26801,valPeriodStart = 1900-01-01, valPeriodEnd = 9999-12-31, addressNr = 7, addressType = 7, addressRow1 = null, addressRow2 = Obere Kirchstr.26, addressRow3 = ноль, страна = CH, postalCode = 8304, город = Walliselln, phoneNr = ноль, faxNr = ноль, sekretaryPhoneNr = ноль, alternatPhoneNr = ноль, pagerNr = ноль]]

Как видите,два объекта идентичны.Вместо этого они отличаются от addressNr и addressType ...

Это фрагмент кода, в котором я создаю запрос:

public static <T> List<T> findBy(EntityManager eM, Class<T> boClass, String whereClause, String whereValue)  
 {
    EntityManager entityManager = eM;
    Query query = entityManager.createQuery("from " + boClass.getName() + " s where s." + whereClause + " = " + whereValue);
    ...
    return (List<T>) query.getResultList();
}

, и это (довольно простой) результирующий запрос:

из ch.ethz.id.wai.pdb.bo.DLDBAddress s, где s.persid = 26801

Это сгенерированный запрос:

Hibernate: 
select
dldbaddres0_.PERSID as PERSID0_,
dldbaddres0_.ADRNUM as ADRNUM0_,
dldbaddres0_.ADRZEIL1 as ADRZEIL3_0_,
dldbaddres0_.ADRZEIL2 as ADRZEIL4_0_,
dldbaddres0_.ADRZEIL3 as ADRZEIL5_0_,
dldbaddres0_.ADRTYP as ADRTYP0_,
dldbaddres0_.ADRAUSWTEL as ADRAUSWTEL0_,
dldbaddres0_.ADRORT as ADRORT0_,
dldbaddres0_.ADRLAND as ADRLAND0_,
dldbaddres0_.ADRFAX as ADRFAX0_,
dldbaddres0_.ADRPSA as ADRPSA0_,
dldbaddres0_.ADRTEL as ADRTEL0_,
dldbaddres0_.ADRPLZ as ADRPLZ0_,
dldbaddres0_.ADRSEKTEL as ADRSEKTEL0_,
dldbaddres0_.BISDAT as BISDAT0_,
dldbaddres0_.VONDAT as VONDAT0_ 
from
NETHZ.V_DLDB_ADRESSE dldbaddres0_ 
where
dldbaddres0_.PERSID=26801

Ивот сущность:

@Entity
@Table(name = "V_DLDB_ADRESSE", schema="NETHZ")
public class DLDBAddress
{
  @Id
  @Column(name = "PERSID", insertable = false, updatable = false)
  private Integer   persid;
  @Temporal(TemporalType.DATE)
  @Column(name = "VONDAT", insertable = false, updatable = false)
  private Date   valPeriodStart;
  @Temporal(TemporalType.DATE)
  @Column(name = "BISDAT", insertable = false, updatable = false)
  private Date   valPeriodEnd;
  @Column(name = "ADRNUM", insertable = false, updatable = false)
  private Integer addressNr;
  @Column(name = "ADRTYP", insertable = false, updatable = false)
  private Integer addressType;
  @Column(name = "ADRZEIL1", insertable = false, updatable = false)
  private String addressRow1;
  @Column(name = "ADRZEIL2", insertable = false, updatable = false)
  private String addressRow2;
  @Column(name = "ADRZEIL3", insertable = false, updatable = false)
  private String addressRow3;
  @Column(name = "ADRLAND", insertable = false, updatable = false)
  private String country;
  @Column(name = "ADRPLZ", insertable = false, updatable = false)
  private String postalCode;
  @Column(name = "ADRORT", insertable = false, updatable = false)
  private String city;
  @Column(name = "ADRTEL", insertable = false, updatable = false)
  private String phoneNr;
  @Column(name = "ADRFAX", insertable = false, updatable = false)
  private String faxNr;
  @Column(name = "ADRSEKTEL", insertable = false, updatable = false)
  private String secretaryPhoneNr;
  @Column(name = "ADRAUSWTEL", insertable = false, updatable = false)
  private String alternatPhoneNr;
  @Column(name = "ADRPSA", insertable = false, updatable = false)
  private String pagerNr;

...

Я что-то упустил?

А, я подключаюсь к БД Oracle.

Заранее спасибо, Франческо

1 Ответ

18 голосов
/ 27 марта 2011
where dldbaddres0_.PERSID=26801

@Id
  @Column(name = "PERSID", insertable = false, updatable = false)

Вы определили PERSID как @Id, который является первичным ключом.Это действительно уникально для вашего приложения?От поведения это не так.Но для Hib это ДОЛЖНО быть.

Итак, что происходит:

  1. В базе данных есть две + записи с PERSID = 26801
  2. Вы запрашиваете их, ГДЕ PERSID = 26801
  3. SQLЗапрос возвращает две + строки
  4. Hib загружает первую и запускает сеанс с ключом PERSID (поскольку он помечен как @Id).Объект помещается в список результатов.
  5. Hib загружает второй, замечает, что объект с таким же @Id уже находится в сеансе, и просто помещает ссылку в список результатов.Данные строк игнорируются.
  6. Таким образом, вы получаете две + копии.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...