createNativeQuery 映射到 POJO(非实体)

2022-09-02 10:34:49

乍一看,我有一个简单的问题:

entityManager()
.createNativeQuery("select count(*) as total, select sum(field) as total_sum ... blabla") 

我想将选择结果写入POJO,如下所示:

public class AggregateStatsDto {

    private int total;

    private long totalSum;

    // getters, setters, cosntructors
}

实现这一目标的最佳方法是什么?

我可以使用JPA 2.1,并尝试使用@SqlResultSetMapping@ConstructorResult

@SqlResultSetMapping(name = "AggregateStatsResult", classes = {
        @ConstructorResult(targetClass = AggregateStatsDto.class,
                columns = {
                        @ColumnResult(name = "total"),
                        @ColumnResult(name = "totalSum")
                })
})
public class AggregateStatsDto {

        private long total;

        private int totalSum;

        // getters, setters, cosntructors
    }

查询:

AggregateStatsDto result = (AggregateStatsDto) entityManager()
    .createNativeQuery("select count(*) as total, select sum(field) as total_sum ... blabla", "AggregateStatsResult")
    .getSingleResult();

但是没有运气。似乎无论如何它都想要@Entity。但我只想要一个POJO。

org.hibernate.MappingException: Unknown SqlResultSetMapping [AggregateStatsResult]"

提前致谢!


答案 1

将@SqlResultSetMapping注释放在实际实体的类中,而不是 DTO 类中。当您在非实体中批注 SqlResultSetMapping 时,实体管理器无法发现您的映射。

@SqlResultSetMapping(name = "AggregateStatsResult", classes = {
    @ConstructorResult(targetClass = AggregateStatsDto.class,
            columns = {
                    @ColumnResult(name = "total"),
                    @ColumnResult(name = "totalSum")
            })
})
@Entity
public class SomeOtherClassWhichIsAnEntity {

答案 2

我通过以下方式解决了我的问题:这是一个查询:

  final Query query = Sale.entityManager().createNativeQuery(...);

然后,我访问了实体管理器内部的Hibernate会话,并应用了标量/结果转换器。仅此而已!

 // access to internal Hibernate of EntityManager
        query.unwrap(SQLQuery.class)
                .addScalar("total", LongType.INSTANCE)
                .addScalar("amountOfSales", LongType.INSTANCE)
                .addScalar("amountOfProducts", LongType.INSTANCE)
                .setResultTransformer(Transformers.aliasToBean(SaleStatsInfo.class));

        ...
        query.getSingleResult();

推荐