亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何以類型安全的方式運行 Hibernate NativeQuery 而不是返回 Object[]

如何以類型安全的方式運行 Hibernate NativeQuery 而不是返回 Object[]

瀟瀟雨雨 2021-09-03 10:21:40
我正在將應用程序從 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:未知實體:[Ljava.lang.Object;研究這個問題似乎表明在使用類型化本機查詢時不可能使用非映射實體(這似乎是一個嚴重且不必要的限制,但我在這里離題了)。問題是:有沒有什么方法可以在實現類型安全的同時執行本地 SQL 查詢,使用 Hibernate 返回一個對象數組,而不會產生編譯器警告?如果沒有,是否有任何明智的選擇?
查看完整描述

3 回答

?
萬千封印

TA貢獻1891條經驗 獲得超3個贊

這種投影有更好的替代方案,而不是默認的Object[]。


您可以使用 JPAjavax.persistence.Tuple結果集,因為Hibernate ORM 5.2.11適用于本機 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();

您可以使用 Hibernate-specific 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();

您還可以使用命名的本機查詢:


 List<PostDTO> postDTOs = entityManager

 .createNamedQuery("PostDTO")

 .setParameter( "fromTimestamp", Timestamp.from(

     LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )

         .toInstant( ZoneOffset.UTC ) ))

 .getResultList();

其中PostDTO查詢是一個命名的本機 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")

         }

     )

 )

酷,對吧?


查看完整回答
反對 回復 2021-09-03
?
慕慕森

TA貢獻1856條經驗 獲得超17個贊

只需通過調用創建它

createNativeQuery("SELECT a.a, a.b, a.c FROM aTable");

它將默認返回一行Object[].

該警告與您的情況無關,因此只需將其壓制即可。


查看完整回答
反對 回復 2021-09-03
  • 3 回答
  • 0 關注
  • 327 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號