我怎样才能避免创建多余的实体



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

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声明。

我的问题是我如何声明这一点,而不必在我的DB中创建表表示的实体?

唉,我没有看到在JPA中这样做的方法。但是,您可以使用hibernate Query对象来实现这一点。使用:

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

然后设置一个结果转换器。在这里看到的:

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

如果您正在使用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<Object[]> rows = (List<Object[]>) query.list();
List<Result> listOfResults = new ArrayList<Result>(rows.size);
for (Object[] row : rows) {
    listOfResults.add(new Result((String) row[0], (String) row[1]));
}

我可以在DataNucleus JPA中运行该查询(略有更改),它工作得很好,因为它应该符合JPA规范。

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

。E使返回列与结果类中的字段名对齐。JPA规范没有说结果类必须是一个实体类;它只是说"结果实例的类"。

您可以定义一个VIEW,它返回查询所需的连接列,并将视图名称用于数据持有人类。

最新更新