createNativeQuery映射到POJO(非实体)

fas*_*sth 10 java sql hibernate jpa java-ee

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

entityManager()
.createNativeQuery("select count(*) as total, select sum(field) as total_sum ... blabla") 
Run Code Online (Sandbox Code Playgroud)

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

public class AggregateStatsDto {

    private int total;

    private long totalSum;

    // getters, setters, cosntructors
}
Run Code Online (Sandbox Code Playgroud)

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

我可以使用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
    }
Run Code Online (Sandbox Code Playgroud)

查询:

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

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

org.hibernate.MappingException: Unknown SqlResultSetMapping [AggregateStatsResult]"
Run Code Online (Sandbox Code Playgroud)

提前致谢!

jef*_*eff 11

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

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

  • 你误解了我的答案.使用我的方法,您仍然在检索普通的POJO(AggregateStatsDto),只需要将SqlResultSetMapping注释放入其他类中,该类是实体管理器识别它的实体. (3认同)
  • JPA 希望我们创建这个中间实体类来返回一个临时查询,这真的很烦人...... (2认同)

fas*_*sth 6

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

  final Query query = Sale.entityManager().createNativeQuery(...);
Run Code Online (Sandbox Code Playgroud)

然后我访问了实体管理器内部的Hibernate会话并应用了scalars/resultTransformer.就这样!

 // 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();
Run Code Online (Sandbox Code Playgroud)

  • `setResultTransformer`现已弃用. (4认同)