Hibernate – TypedQuery.getResultList()返回同一对象的列表
以下是对问题的更多和更好的描述:
我做一个简单的选择查询。 返回列表包含确切的记录/对象数,就好像我在DB中执行相同的查询一样,但问题是所有对象都相同/相同。
例如,这是DB中的结果(我删除了空值):
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中看到它:
地址ArrayList(id = 81)
elementData Object [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 List findBy(EntityManager eM, Class boClass, String whereClause, String whereValue) { EntityManager entityManager = eM; Query query = entityManager.createQuery("from " + boClass.getName() + " s where s." + whereClause + " = " + whereValue); ... return (List) 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 DB。
在此先感谢Francesco
where dldbaddres0_.PERSID=26801 @Id @Column(name = "PERSID", insertable = false, updatable = false)
您将PERSID定义为@Id,这是一个主键。 它对您的应用来说真的很独特吗? 从行为来看并非如此。 但对于Hib来说,它必须是。
那么会发生什么:
- 数据库中有两条+记录,PERSID = 26801
- 您查询它们WHERE PERSID = 26801
- SQL Query返回两个+行
- Hib加载第一个,并进入会话,PERSID作为键(因为它标记为@Id)。 对象放入结果列表中。
- Hib加载第二个,注意到具有相同@Id的对象已经在会话中,并且只是将引用放入结果列表中。 行数据被忽略。
- 因此你得到两个+副本。
- Java JSON -Jackson-嵌套元素
- Java,Spark和Cassandra java.lang.ClassCastException:com.datastax.driver.core.DefaultResultSetFuture无法转换为阴影
- 使用getCurrentSession()时获取“找不到当前线程的会话”exception
- 使用hibernate正确使用Spring mvc 3(Spring ORM)
- 除非访问集合,否则Hibernate OneToMany FetchType.LAZY无法正常工作?
- 类型,属性,实例和值之间的关系
- 如何防止Hibernate + c3p0 + MySql创建大量睡眠连接?
- 如何构建一个动态查询,该查询添加了迄今为止的天数,并使用条件API将该日期与另一个日期进行比较?
- 如何在Spring / EJB / Mockito …代理上处理内部调用?
- hibernate和inheritance(TABLE_PER_CLASS)
- 在什么条件下我们需要在数据库中使用复合键