javax.persistence.PersistenceException:org.hibernate.MappingException:未知实体:it.*.PoolStateResult |在 DTO(而非实体)中映射结果
javax.persistence.PersistenceException: org.hibernate.MappingException: Unknown entity: it.*.PoolStateResult | Map a result in a DTO (not an Entity)
使用:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>1.5.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
这是我的 DTO。它不是数据库上的实体。我只想将它用于映射
public class PoolStateResult {
private Integer totalCodes;
private Integer assignedCodes;
private Integer availableCodes;
private Date startDateValidate;
private Date endDateValidate;
constructors
getters and setters
这是DAO的内容
Query q = em.createNativeQuery(" SELECT p.start_validity_date as startDateValidate, "
+ " p.end_validity_date as endDateValidate, "
+ " (SELECT count(*) from POOL_CODES p WHERE p.id_pool = :poolCode) as totalCodes, "
+ " (SELECT count(*) "
+ " from VOUCHER v "
+ " WHERE v.id_reference_pool = :poolCode "
+ " AND v.status = 'ASSEGNATO') as assignedCodes, "
+ " (SELECT count(*) "
+ " from VOUCHER v, POOL_CODES p "
+ " WHERE v.id_reference_pool = p.id_pool "
+ " AND v.id_reference_pool = :poolCode "
+ " AND v.status = 'ASSEGNATO' "
+ " and p.end_validity_date < sysdate) as availableCodes "
+ " from POOL_CODES p "
+ " WHERE p.id_pool = :poolCode",PoolStateResult.class);
q.setParameter("poolCode", "poolCode");
return (PoolStateResult) q.getSingleResult();
我在配置中添加了这个包class
entityManagerFactory.setPackagesToScan(
env.getProperty("entitymanager.packages.to.scan"),
这是个例外
javax.persistence.NoResultException: No entity found for query
at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:532)
有没有一种方法可以针对所有实体表自动强制映射,或者使用 hibernate 的唯一方法是为这些类型的查询编写映射?
这是使用 Hibernate 映射非实体 Java 对象的最佳且唯一的方法吗?
@SqlResultSetMapping(
name="getPoolStateResult",
classes={
@ConstructorResult(
targetClass=PoolStateResult.class,
columns={
@ColumnResult(name="totalCodes", type=Integer.class),
@ColumnResult(name="assignedCodes", type=Integer.class),
@ColumnResult(name="availableCodes", type=Integer.class),
@ColumnResult(name="startDateValidate", type=Date.class),
@ColumnResult(name="endValidityDate", type=Date.class)
}
)
}
)
那么hibernate在这种情况下的优势在哪里呢?
谢谢
尝试稍微改变一下您的查询创建:
1) 添加 NEW package.Class
到 select 列表
String queryString =
"SELECT new com.mypackage.PoolStateResult("
+ "p.start_validity_date as startDateValidate, "
+ " p.end_validity_date as endValidityDate, "
+ " (SELECT count(*) from POOL_CODES p WHERE p.id_pool = :poolCode) as totalCodes, "
+ " (SELECT count(*) "
+ ")"
+ " from VOUCHER v "
...
2) 使用将 sql 映射名称传递给的 createNativeQuery 方法作为第二个参数:
em.createNativeQuery(queryString, "getPoolStateResult");
没有 JPA 和 Hibernate 不能在没有任何映射信息的情况下自动将查询结果映射到 DTO。您要么以编程方式映射结果,要么像您在示例中所做的那样在 @SqlResultSetMapping
中定义构造函数调用。
如果您想将结果映射到实体,则不需要这样做。 Hibernate 然后尝试使用实体的映射定义来映射查询结果。因此,您的查询结果需要 return 所有实体属性,并且它们的名称必须与您在实体映射中使用的名称相同。我在 series of blog posts about @SqlResultMapping
.
中更详细地解释了这一点
关于使用 Hibernate 进行此类查询的好处:
如果这是您在事务中执行的唯一数据库交互,Hibernate 不会为您提供任何好处。但它允许您在 Hibernate 会话中使用此查询,因此在与 Hibernate 在该会话中执行的所有其他操作相同的事务中。
使用:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>1.5.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
这是我的 DTO。它不是数据库上的实体。我只想将它用于映射
public class PoolStateResult {
private Integer totalCodes;
private Integer assignedCodes;
private Integer availableCodes;
private Date startDateValidate;
private Date endDateValidate;
constructors
getters and setters
这是DAO的内容
Query q = em.createNativeQuery(" SELECT p.start_validity_date as startDateValidate, "
+ " p.end_validity_date as endDateValidate, "
+ " (SELECT count(*) from POOL_CODES p WHERE p.id_pool = :poolCode) as totalCodes, "
+ " (SELECT count(*) "
+ " from VOUCHER v "
+ " WHERE v.id_reference_pool = :poolCode "
+ " AND v.status = 'ASSEGNATO') as assignedCodes, "
+ " (SELECT count(*) "
+ " from VOUCHER v, POOL_CODES p "
+ " WHERE v.id_reference_pool = p.id_pool "
+ " AND v.id_reference_pool = :poolCode "
+ " AND v.status = 'ASSEGNATO' "
+ " and p.end_validity_date < sysdate) as availableCodes "
+ " from POOL_CODES p "
+ " WHERE p.id_pool = :poolCode",PoolStateResult.class);
q.setParameter("poolCode", "poolCode");
return (PoolStateResult) q.getSingleResult();
我在配置中添加了这个包class
entityManagerFactory.setPackagesToScan(
env.getProperty("entitymanager.packages.to.scan"),
这是个例外
javax.persistence.NoResultException: No entity found for query
at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:532)
有没有一种方法可以针对所有实体表自动强制映射,或者使用 hibernate 的唯一方法是为这些类型的查询编写映射? 这是使用 Hibernate 映射非实体 Java 对象的最佳且唯一的方法吗?
@SqlResultSetMapping(
name="getPoolStateResult",
classes={
@ConstructorResult(
targetClass=PoolStateResult.class,
columns={
@ColumnResult(name="totalCodes", type=Integer.class),
@ColumnResult(name="assignedCodes", type=Integer.class),
@ColumnResult(name="availableCodes", type=Integer.class),
@ColumnResult(name="startDateValidate", type=Date.class),
@ColumnResult(name="endValidityDate", type=Date.class)
}
)
}
)
那么hibernate在这种情况下的优势在哪里呢?
谢谢
尝试稍微改变一下您的查询创建:
1) 添加 NEW package.Class
到 select 列表
String queryString =
"SELECT new com.mypackage.PoolStateResult("
+ "p.start_validity_date as startDateValidate, "
+ " p.end_validity_date as endValidityDate, "
+ " (SELECT count(*) from POOL_CODES p WHERE p.id_pool = :poolCode) as totalCodes, "
+ " (SELECT count(*) "
+ ")"
+ " from VOUCHER v "
...
2) 使用将 sql 映射名称传递给的 createNativeQuery 方法作为第二个参数:
em.createNativeQuery(queryString, "getPoolStateResult");
没有 JPA 和 Hibernate 不能在没有任何映射信息的情况下自动将查询结果映射到 DTO。您要么以编程方式映射结果,要么像您在示例中所做的那样在 @SqlResultSetMapping
中定义构造函数调用。
如果您想将结果映射到实体,则不需要这样做。 Hibernate 然后尝试使用实体的映射定义来映射查询结果。因此,您的查询结果需要 return 所有实体属性,并且它们的名称必须与您在实体映射中使用的名称相同。我在 series of blog posts about @SqlResultMapping
.
关于使用 Hibernate 进行此类查询的好处: 如果这是您在事务中执行的唯一数据库交互,Hibernate 不会为您提供任何好处。但它允许您在 Hibernate 会话中使用此查询,因此在与 Hibernate 在该会话中执行的所有其他操作相同的事务中。