gpt4 book ai didi

java - 如何以类型安全的方式运行 Hibernate NativeQuery 而不是返回 Object[]

转载 作者:行者123 更新时间:2023-11-30 06:43:20 26 4
gpt4 key购买 nike

我正在将应用程序从 Hibernate 4.x 迁移到 Hibernate 5.3.6。该应用程序有这样的查询:

SQLQuery query = getSession().createSQLQuery("SELECT a.a, a.b, a.c FROM aTable");

作为方法createSQLQuery已被弃用,我首先将方法调用替换为 Hibernate Javadoc 中建议的替代方法,即使用 createNativeQuery:

NativeQuery query = getSession().createNativeQuery("SELECT a.a, a.b, a.c FROM aTable");

问题在于它会产生编译器警告“NativeQuery 是原始类型。对泛型 NativeQuery 的引用应该被参数化”。此外,既然类型化查询可用,我当然想从中受益。所以我将查询更改为

NativeQuery<Object[]> query = getSession().createNativeQuery("SELECT a.a, a.b, a.c FROM aTable", Object[].class);

现在的问题是用

执行查询
List<Object[]> retList = query.list();

产生错误

javax.persistence.PersistenceException: org.hibernate.MappingException: Unknown entity: [Ljava.lang.Object;

研究问题seems to indicate在使用类型化 native 查询时不可能使用非映射实体(这似乎是一个严重且不必要的限制,但我在这里离题)。

问题:有什么方法可以使用 Hibernate 执行返回对象数组的 native SQL 查询而不产生编译器警告同时实现类型安全?如果没有,是否有任何明智的选择?

最佳答案

除了默认的 Object[] 之外,对于此类投影还有更好的选择。

  1. 您可以使用 JPA javax.persistence.Tuple结果集,自 Hibernate ORM 5.2.11适用于 native SQL:

     List<Tuple> postDTOs = entityManager
    .createNativeQuery(
    "SELECT " +
    " p.id AS id, " +
    " p.title AS title " +
    "FROM Post p " +
    "WHERE p.created_on > :fromTimestamp", Tuple.class)
    .setParameter( "fromTimestamp", Timestamp.from(
    LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
    .toInstant( ZoneOffset.UTC ) ))
    .getResultList();
  2. 您可以使用特定于 Hibernate 的 ResultTransformer它允许您构建非常复杂的 DTO 结构(例如图形):

     List postDTOs = entityManager
    .createNativeQuery(
    "select " +
    " p.id as \"id\", " +
    " p.title as \"title\" " +
    "from Post p " +
    "where p.created_on > :fromTimestamp")
    .setParameter( "fromTimestamp", Timestamp.from(
    LocalDateTime.of( 2016, 1, 1, 0, 0, 0 ).toInstant( ZoneOffset.UTC ) ))
    .unwrap( org.hibernate.query.NativeQuery.class )
    .setResultTransformer( Transformers.aliasToBean( PostDTO.class ) )
    .getResultList();
  3. 您还可以使用命名 native 查询:

     List<PostDTO> postDTOs = entityManager
    .createNamedQuery("PostDTO")
    .setParameter( "fromTimestamp", Timestamp.from(
    LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
    .toInstant( ZoneOffset.UTC ) ))
    .getResultList();

    PostDTO 查询是一个命名的 native SQL 查询,如下所示:

     @NamedNativeQuery(
    name = "PostDTO",
    query =
    "SELECT " +
    " p.id AS id, " +
    " p.title AS title " +
    "FROM Post p " +
    "WHERE p.created_on > :fromTimestamp",
    resultSetMapping = "PostDTO"
    )
    @SqlResultSetMapping(
    name = "PostDTO",
    classes = @ConstructorResult(
    targetClass = PostDTO.class,
    columns = {
    @ColumnResult(name = "id"),
    @ColumnResult(name = "title")
    }
    )
    )

很酷,对吧?

关于java - 如何以类型安全的方式运行 Hibernate NativeQuery 而不是返回 Object[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52200422/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com