代码之家  ›  专栏  ›  技术社区  ›  Angelo

javax。坚持不懈PersistenceException:组织。冬眠MappingException:未知实体:it。*。PoolStateResult |将结果映射到DTO(非实体)

  •  3
  • Angelo  · 技术社区  · 7 年前

    使用:

    <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。它不是DB上的实体。我只想将其用于映射

    public class PoolStateResult {
    
        private Integer totalCodes;
        private Integer assignedCodes;
        private Integer availableCodes;
    
        private Date startDateValidate;
        private Date endDateValidate;
    
    constructors
    getters and setters
    

    这就是道的内容

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

    我在configuration类中添加此包

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

    那么,在这种情况下,休眠的优势在哪里呢?

    谢谢

    2 回复  |  直到 7 年前
        1
  •  3
  •   Thorben Janssen    7 年前

    没有任何映射信息,JPA和Hibernate无法将查询结果自动映射到DTO。要么以编程方式映射结果,要么在 @SqlResultSetMapping ,正如您在示例中所做的。

    如果要将结果映射到实体,则不需要这样做。然后Hibernate尝试使用实体的映射定义来映射查询结果。因此,查询结果需要返回所有实体属性,并且它们必须与您在实体映射中使用的名称相同。我在 series of blog posts about @SqlResultMapping .

    关于使用Hibernate进行此类查询的好处: 如果这是您在事务中执行的唯一数据库交互,那么Hibernate不会给您带来任何好处。但它允许您在Hibernate会话中使用此查询,因此可以在与Hibernate在该会话中执行的所有其他操作相同的事务中使用此查询。

        2
  •  0
  •   Maciej Kowalski    7 年前

    尝试稍微更改您的查询创建:

    1) 添加 NEW package.Class 到选择列表

    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) 使用createNativeQuery方法,将sql映射名称作为第二个参数传递给该方法:

    em.createNativeQuery(queryString, "getPoolStateResult");