如何避免创建多余的实体?

在我当前的项目中,我需要执行一些本机查询,从查询中加入的表中选择一些字段,例如:

SELECT t1.col1, t2.col5 FROM t1 JOIN t2 ON t2.id = t1.t2_id 

我试着将它们存放在类似的类中

 class Result { String t1_col1; String t2_col5; } 

运用

 Query q = entityManager.createNativeQuery( "THE SQL SELECT" , Result.class ); 

JPA现在抱怨(“未知实体:结果”)类“结果”不是可能需要将列映射到对象的实体。 我还尝试在结果类中重复@Column声明。

我的问题是如何声明这一点而不必在我的数据库中创建表示为表格的entites?

如果您使用JPA / Hibernate执行SQL查询,那么您使用的是错误的工具。 Hibernate是一个ORM,你应该将表映射到实体。 这就是JPA的重点。 我只想执行SQL查询,使用JDBC(例如Spring的JdbcTemplate)

一旦table1和table2映射到实体(让我们调用这些实体T1和T2),您将不再需要这些SQL查询,因为JPQL只能选择实体的某些字段。 您的查询可能如下所示(取决于t1和t2之间的关联):

 select t1.col1, t2.col5 from T1 t1 join t1.t2 t2 

你只需要迭代结果(Object []列表)来构建你的结果(这是一个DTO,而不是一个映射的实体):

 List rows = (List) query.list(); List listOfResults = new ArrayList(rows.size); for (Object[] row : rows) { listOfResults.add(new Result((String) row[0], (String) row[1])); } 

唉,我认为在JPA中没有办法做到这一点。 但是,您可以使用hibernate Query对象执行此操作。 获得它使用:

 org.hibernate.Query query = q.unwrap(org.hibernate.Query.class); 

然后设置结果转换器。 看到这里 :

 query.setResultTransformer(Transformers.aliasToBean(Result.class)); 

我可以在DataNucleus JPA中运行该查询(稍作更改)并且它可以正常工作,因为它应该符合JPA规范。

 SELECT t1.col1 AS t1_col1, t2.col5 AS t2_col5 FROM t1 JOIN t2 ON t2.id = t1.t2_id 

即使返回列与结果类中的字段名称对齐。 JPA规范没有说结果类必须是Entity类; 它只是简单地说“结果实例的类”。

您可能会定义一个VIEW,它返回查询所需的连接列,并使用您的数据持有者类的视图名称。