Expresión de constructor JPQL – org.hibernate.hql.ast.QuerySyntaxException: tabla no asignada

Mi problema original era https://stackoverflow.com/questions/12172614/hql-join-without-foreign-key-reference, pero no pude encontrar ninguna solución para esto, por lo tanto, seguí adelante con la consulta nativa usando JPA. createNativeQuery of entityManager devuelve el objeto Query que a su vez devuelve List . No quiero tratar con índices mientras itero la lista porque es propenso a errores en la naturaleza. Por lo tanto, busqué alguna otra solución y encontré expresiones de Constructor de JPQL como una de la solución.

La estructura de la mesa es

 Schema1 -TableA - NameColumn - PhoneColumn 

La clase correspondiente de Java es

  public class PersonSearch implements Serializable { public PersonSearch (String NameColumn, String PhoneColumn) { this.name = NameColumn; this.phone = PhoneColumn; } private String name; private String phone; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } } 

Query es

  Select NEW com.xyz.PersonSearch(ms.NameColumn, ms.PhoneColumn) From Schema1.TableA ms Where ms.PhoneColumn='9134409930' 

al ejecutar esta consulta utilizando la API de entityManager

 entityManager.createQuery(queryString, PersonSearch.class); 

obteniendo el error debajo

 Caused by: org.hibernate.hql.ast.QuerySyntaxException: Schema1.TableA is not mapped [Select NEW com.xyz.PersonSearch(ms.NameColumn, ms.PhoneColumn) From Schema1.TableA ms Where ms.PHONE='9134409930'] 

¿Qué pasa con mi código? Alguna idea ?

según el libro “Pro EJB 3 Java Persistence API”

Expresiones de constructor

Una forma más poderosa de la cláusula SELECT que involucra expresiones múltiples es la expresión del constructor, que especifica que los resultados de la consulta se almacenarán utilizando un tipo de objeto especificado por el usuario. Considere la siguiente consulta:

 SELECT NEW example.EmployeeDetails(e.name, e.salary, e.department.name) FROM Employee e 

El tipo de resultado de esta consulta es el tipo example.EmployeeDetails . A medida que el procesador de consultas itera sobre los resultados de la consulta, crea instancias nuevas de EmployeeDetails utilizando el constructor que coincide con los tipos de expresión enumerados en la consulta. En este caso, los tipos de expresión son String, Double y String, por lo que el motor de búsqueda buscará un constructor con esos tipos de clases para los argumentos. Cada fila en la colección de consultas resultante es, por lo tanto, una instancia de EmployeeDetails contiene el nombre del empleado, el salario y el nombre del departamento.

El tipo de objeto de resultado se debe consultar utilizando el nombre completo del objeto. Sin embargo, la clase no tiene que estar asignada a la base de datos de ninguna manera. Cualquier clase con un constructor compatible con las expresiones enumeradas en la cláusula SELECT se puede usar en una expresión de constructor.

Las expresiones de constructor son herramientas potentes para construir objetos de transferencia de datos de grano grueso o visualizar objetos para usar en otros niveles de aplicación. En lugar de construir manualmente estos objetos, se puede usar una sola consulta para reunir objetos de vista listos para su presentación en una página web.

El código de ejemplo es el siguiente

 List result = em.createQuery("SELECT NEW example.EmpMenu(e.name, e.department.name) " + "FROM Project p JOIN p.employees e " + "WHERE p.name = ?1 " + "ORDER BY e.name").setParameter(1, projectName).getResultList(); 

La clase EmpMenu es un pojo simple, sin anotaciones, pero tiene el constructor correcto para que coincida con la expresión del constructor. El resultado es una lista de objetos EmpMenu para cada fila devuelta.

Creo que la parte de su SQL “…. De Schema1.TableA ms ..” debe referirse a una entidad que está mapeada. Entonces debería tener una entidad asignada a TableA, y luego jpql debería ser algo más como “…. From MyTableAEntity ms …” donde MyTableAEntity tiene todas las anotaciones jpa correctas asignándola a la tabla DB TableA. Como dice el fragmento de libro, el objective de “SELECCIONAR NUEVA …” no tiene que estar correlacionado, pero sí lo hace la entidad a la que se hace referencia en la cláusula FROM.