使用内部联接使用hibernate返回多个对象类型

我似乎在使用hibernate中的查询时遇到了一些困难。 我正在两个表上执行内连接。

SELECT * FROM product p INNER JOIN warehouse w ON p.wid = w.id 

产品表:

 id | name | wid | price | stock ..... 

仓库表:

 id | name | city | lat | long ..... 

加入结果:

 id | name | wid | price | stock | id | name | city | lat | long ..... 

当我运行查询..

 Session.createSQLQuery(this.query) .addEntity("p", Product.class) .addEntity("w", Warehouse.class).list(); 

因此,对于每个结果,我得到一个包含Product objectWarehouse object

这是预料之中的。 问题是hibernate将产品的id和名称分配给仓库对象id和name属性。 就创建Warehouse项目而言,好像连接结果中的前两列都过度了。 Product对象始终包含正确的数据。

有关找到解决此问题的方法的任何建议,因此非常感谢表示正确仓库数据的id和name列。

提前致谢。

使用{}表单可以避免列名重复出现问题:

 SELECT {p.*}, {w.*} FROM product p INNER JOIN warehouse w ON p.wid = w.id 

从Hibernate参考文档 ,第18.1.4节。 返回多个实体:

到目前为止,假设结果集列名与映射文档中指定的列名相同。 对于连接多个表的SQL查询,这可能会有问题,因为相同的列名可以出现在多个表中。

在以下查询中需要列别名注入(很可能会失败):

 sess.createSQLQuery("SELECT c.*, m.* FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID") .addEntity("cat", Cat.class) .addEntity("mother", Cat.class) 

该查询旨在每行返回两个Cat实例:一只猫及其母亲。 但是,查询将失败,因为存在名称冲突; 实例映射到相同的列名称。 此外,在某些数据库上,返回的列别名很可能位于“c.ID”,“c.NAME”等forms上,它们不等于映射中指定的列(“ID”和“NAME”) 。

以下表单不容易受到列名重复的影响:

 sess.createSQLQuery("SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID") .addEntity("cat", Cat.class) .addEntity("mother", Cat.class) 

此查询指定:

SQL查询字符串,Hibernate的占位符为查询返回的实体注入列别名上面使用的{cat.*}{mother.*}表示法是“所有属性”的简写。

正如coding_idiot所说,也许您不知道查询结果的实体,因为它们来自不同的类,您可以访问元素中的每个对象。

  1. 创建List以检索查询结果(示例: Listobjs = (List)query.getResultList();
  2. 使用for迭代遍历此数组(例如: for (Object obj : objs){...}
  3. List每个元素都有一个Object[]因此将每个元素强制转换为此类(例如: Object[] o = (Object[]) obj;
  4. 通过索引号访问元素(例如: o[4]

代码示例:

  Query query = JPA.em().createNativeQuery("SELECT * FROM product p INNER JOIN warehouse w ON p.wid = w.id"); /* I suppose that it return fields sorted by entities and field in database: * * 0: product.id | 1: product.name | 2: product.wid | 3: product.price | 4: product.stock | n-1: product.N-1Field * n: warehouse.id | n+1: name | n+2: warehouse.city | n+3: warehouse.lat | n+4: warehouse.long | m-1: warehouse.M-1Field * * Join result: id | name | wid | price | stock | ... | id | name | city | lat | long | ... */ List objs = (List)query.getResultList(); for (Object obj : objs) { Object[] o = (Object[]) obj; String productId = String.valueOf(o[0]); String productName = String.valueOf(o[1]); String productWid = String.valueOf(o[2]); ... } 

参考

如果实体不是来自同一个类,那么这是一个示例:

 public static void main(String[] args) { Session sess = NewHibernateUtil.getSessionFactory().openSession(); SQLQuery q = null; String query = "select a.*, u.* from user u, account a where a.iduser=u.iduser"; q = sess.createSQLQuery(query); q.addEntity(User.class); q.addEntity(Account.class); List lst = q.list(); System.out.println("" + lst.size()); for (int i = 0; i < lst.size(); i++) { System.out.println(((Object[]) lst.get(i))[0]); //account bean, actually this is in reverse order - so this is user bean System.out.println(((Object[]) lst.get(i))[1]); //user bean & this account bean } sess.close(); }