休眠-TypedQuery.getResultList()返回相同对象的列表

这是对该问题的更多甚至更好的描述:

我做一个简单的选择查询。返回列表包含确切的记录/对象数,就好像我在数据库中进行相同的查询一样,但是问题在于所有对象都是相同/相同的。

例如,这是数据库中的结果(我删除了空值):

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瓦利塞伦

这是变量地址的内容,正如我在执行查询后的调试过程中可以在Eclipse中看到的那样:

地址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 =

Obere Kirchstr。26,addressRow3 = null,country = CH,postalCode = 8304,city =

Walliselln,phoneNr = null,faxNr = null,sekretaryPhoneNr = null,alternatPhoneNr

= null,pagerNr = null]

DLDBAddress [persid = 26801,valPeriodStart = 1900-01-01,valPeriodEnd =

9999-12-31,addressNr = 7,addressType = 7,addressRow1 = null,addressRow2 =

Obere Kirchstr。26,addressRow3 = null,country = CH,postalCode = 8304,city =

Walliselln,phoneNr = null,faxNr = null,sekretaryPhoneNr = null,alternatPhoneNr

= null,pagerNr = null]]

如您所见,这两个对象是相同的。它们应该不同于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.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数据库。

在此先感谢Francesco

回答:

where dldbaddres0_.PERSID=26801

@Id

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

您将PERSID定义为@Id,这是一个主键。它对于您的应用程序来说真的很独特吗?从行为来看不是。但是对于希伯来说一定是。

那么会发生什么:

  1. 您在数据库中有两个以上的记录,PERSID = 26801
  2. 您查询他们WHERE PERSID = 26801
  3. SQL查询返回两行以上
  4. Hib将第一个加载并进入会话,并以PERSID作为键(因为它被标记为@Id)。对象被放入结果列表。
  5. Hib加载第二个,注意会话中已经有一个具有相同@Id的对象,并将引用放入结果列表中。行数据将被忽略。
  6. 这样就得到了两个以上的副本。

以上是 休眠-TypedQuery.getResultList()返回相同对象的列表 的全部内容, 来源链接: utcz.com/qa/411073.html

回到顶部