videos tiempo polares pardo osos oso meme los hibernando hibernan hibernacion duermen donde dibujo cuanto como animales java hibernate inner-join

java - tiempo - oso pardo hibernacion



Devolviendo múltiples tipos de objetos usando hibernación usando una unión interna (3)

Parece que estoy teniendo algunas dificultades con una consulta en hibernación. Estoy realizando una unión interna en dos tablas.

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

Tabla de productos:

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

Mesa de almacén:

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

El resultado de la unión:

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

Cuando ejecuto la consulta ..

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

Entonces, por cada resultado, obtengo un objeto que contiene un Product object y un Warehouse object .

Esto es lo esperado. El problema es que la hibernación asigna el id y el nombre del producto a la propiedad id y name de los objetos del almacén. Es como si las dos primeras columnas en el resultado de la unión estuvieran sobre montadas cuando se trata de crear el proyecto de Warehouse. El objeto Producto siempre contiene los datos correctos.

Cualquier sugerencia sobre cómo solucionar este problema para que las columnas de ID y nombre que representan los datos correctos del Almacén sean muy apreciadas.

Gracias por adelantado.


Como dijo coding_idiot, quizás no conozca la entidad para el resultado de su consulta porque son de diferentes clases, puede acceder a todos los objetos del elemento.

  1. Cree una List<Object> para recuperar el resultado de la consulta (Ejemplo: List<Object> objs = (List<Object>)query.getResultList(); )
  2. Iterar a través de esta matriz usando un for (Ejemplo: for (Object obj : objs){...} )
  3. Todos los elementos de la List<Object> tienen un Object[] así que convierta todos los elementos en esta clase (Ejemplo: Object[] o = (Object[]) obj; )
  4. Acceso al elemento a través de su número de índice (Ejemplo: o[4] )

Ejemplo de código:

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<Object> objs = (List<Object>)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]); ... }


Utilice el formulario {} para evitar problemas con la duplicación de nombres de columna:

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

De la documentación de referencia de Hibernate , sección 18.1.4. Devolviendo múltiples entidades:

Hasta ahora, se asume que los nombres de columna del conjunto de resultados son los mismos que los nombres de columna especificados en el documento de mapeo. Esto puede ser problemático para las consultas SQL que se unen a varias tablas, ya que los mismos nombres de columna pueden aparecer en más de una tabla.

La inyección de alias de columna es necesaria en la siguiente consulta (que probablemente fallará):

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

La consulta estaba destinada a devolver dos instancias de Cat por fila: un gato y su madre. Sin embargo, la consulta fallará porque existe un conflicto de nombres; las instancias se asignan a los mismos nombres de columna. Además, en algunas bases de datos, los alias de columna devueltos estarán probablemente en la forma "c.ID", "c.NAME", etc., que no son iguales a las columnas especificadas en las asignaciones ("ID" y "NAME") .

El siguiente formulario no es vulnerable a la duplicación de nombres de columna:

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

Esta consulta especifica:

la cadena de consulta SQL, con marcadores de posición para que Hibernate inyecte alias de columna a las entidades devueltas por la consulta. La notación {cat.*} y {mother.*} utilizada anteriormente es una abreviatura de "todas las propiedades".


Reference

En caso de que las entidades no pertenezcan a la misma clase, aquí hay un ejemplo:

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(); }