将NativeQuery结果映射到POJO
我试图使用带@ConstructorResult的@SqlResultSetMapping将Native查询的结果映射到POJO。 这是我的代码:
@SqlResultSetMapping(name="foo", classes = { @ConstructorResult( targetClass = Bar.class, columns = { @ColumnResult(name = "barId", type = Long.class), @ColumnResult(name = "barName", type = String.class), @ColumnResult(name = "barTotal", type = Long.class) }) }) public class Bar { private Long barId; private String barName; private Long barTotal; ...
然后在我的DAO中:
Query query = em.createNativeQueryBar(QUERY, "foo"); ... set some parameters ... List list = (List) query.getResultList();
我已经读过这个function仅在JPA 2.1中受支持,但这就是我正在使用的。 这是我的依赖:
org.hibernate.javax.persistence hibernate-jpa-2.1-api 1.0.0.Final
我发现了一些资源,包括这一个: jpa 2.1中的@ConstructorResult映射 。 但我仍然没有运气。
我错过了什么? 为什么不能找到SqlResultSetMapping?
javax.persistence.PersistenceException: org.hibernate.MappingException: Unknown SqlResultSetMapping [foo]
不应将 @SqlResultSetMapping
注释放在POJO上 。 把它放在(任何) @Entity
类。 “Unknown SqlResultSetMapping [foo]”告诉您,JPA提供程序在名称’foo’下没有看到任何映射。 请参阅我的另一个答案以获取正确的示例
- JPA-在非实体类中连接两个表
简短的工作示例:
-
DTO POJO课程
@lombok.Getter @lombok.AllArgsConstructor public class StatementDto { private String authorName; private Date createTime; }
-
存储库bean:
@Repository public class StatementNativeRepository { @PersistenceContext private EntityManager em; static final String STATEMENT_SQLMAP = "Statement-SQL-Mapping"; public List
findPipelinedStatements() { Query query = em.createNativeQuery( "select author_name, create_time from TABLE(SomePipelinedFun('xxx'))", STATEMENT_SQLMAP); return query.getResultList(); } @SqlResultSetMapping(name= STATEMENT_SQLMAP, classes = { @ConstructorResult(targetClass = StatementDto.class, columns = { @ColumnResult(name="author_name",type = String.class), @ColumnResult(name="create_time",type = Date.class) } ) }) @Entity class SQLMappingCfgEntity{@Id int id;} // <- walkaround }
我能够这样做:
Session session = em().unwrap(Session.class); SQLQuery q = session.createSQLQuery("YOUR SQL HERE"); q.setResultTransformer( Transformers.aliasToBean( MyNotMappedPojoClassHere.class) ); List postList = q.list();
@Entity @SqlResultSetMapping(name="ConnexionQueryBean", entities={ @EntityResult(entityClass=com.collecteJ.business.bean.ConnexionQueryBean.class, fields={ @FieldResult(name="utilisateurId", column="UTILISATEUR_ID"), @FieldResult(name="nom", column="NOM"), @FieldResult(name="prenom", column="PRENOM"), @FieldResult(name="nomConnexion", column="NOM_CONNEXION"), @FieldResult(name="codeAgence", column="CODE_AGENCE"), @FieldResult(name="codeBanque", column="CODE_BANQUE"), @FieldResult(name="codeDevise", column="CODE_DEVISE"), @FieldResult(name="codeCollecteur", column="CODE_COLLECTEUR")}) }) public class ConnexionQueryBean implements Serializable { @Id private long utilisateurId; private String codeCollecteur; private String nom; private String prenom; private String nomConnexion; private String codeAgence; private String codeBanque; private String codeDevise; public ConnexionQueryBean() { } public long getUtilisateurId() { return utilisateurId; } public void setUtilisateurId(long utilisateurId) { this.utilisateurId = utilisateurId; } public String getCodeCollecteur() { return codeCollecteur; } public void setCodeCollecteur(String codeCollecteur) { this.codeCollecteur = codeCollecteur; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getPrenom() { return prenom; } public void setPrenom(String prenom) { this.prenom = prenom; } public String getNomConnexion() { return nomConnexion; } public void setNomConnexion(String nomConnexion) { this.nomConnexion = nomConnexion; } public String getCodeAgence() { return codeAgence; } public void setCodeAgence(String codeAgence) { this.codeAgence = codeAgence; } public String getCodeBanque() { return codeBanque; } public void setCodeBanque(String codeBanque) { this.codeBanque = codeBanque; } public String getCodeDevise() { return codeDevise; } public void setCodeDevise(String codeDevise) { this.codeDevise = codeDevise; } @Override public String toString() { return "ConnexionQueryBean{" + "utilisateurId=" + utilisateurId + ", codeCollecteur=" + codeCollecteur + ", nom=" + nom + ", prenom=" + prenom + ", nomConnexion=" + nomConnexion + ", codeAgence=" + codeAgence + ", codeBanque=" + codeBanque + ", codeDevise=" + codeDevise + '}'; }
这实际上不是一个实体,因为它与任何数据库表都不匹配。 但@Entity
和@Id
注释是JPA理解映射的强制措施。 如果您真的不想在该类中使用@Entity / @Id
,则可以删除@SqlResultSetMapping
注释并将其放在任何其他实体中,只要JPA可以扫描它。
您还应该确保@ComponentScan
内容对应的包,如果您使用的是基于java的spring配置,则应该在META-INF
目录下的persistence.xml/orm.xml
显式声明您的实体。
这是电话
String connexionQuery = "SELECT u.UTILISATEUR_ID, u.NOM, u.PRENOM, u.NOM_CONNEXION, a.CODE_AGENCE, a.CODE_BANQUE, a.CODE_DEVISE, c.CODE_COLLECTEUR FROM UTILISATEUR u, AGENCE a, COLLECTEUR c " + " WHERE (a.CODE_AGENCE = c.CODE_AGENCE AND u.UTILISATEUR_ID = c.UTILISATEUR_ID AND u.NOM_CONNEXION = '"+nomConnextion+"')"; ConnexionQueryBean ConnexionResults = (ConnexionQueryBean) defaultService.getEntityManager().createNativeQuery(connexionQuery,"ConnexionQueryBean").getSingleResult(); System.out.println(ConnexionResults.toString());
我正在使用Spring,JPA 2.1,Hibernate 5和Oracle,我认为这可能不适用于JPA较低版本,找到更多http://www.thoughts-on-java.org/result-set-mapping-complex-映射/
QLRM可以替代: http ://simasch.github.io/qlrm/
它与特定的JPA实现无关,也适用于JDBC。
- Hibernatevalidation器在正则表达式匹配上吃CPU
- 缺少序列或表:hibernate_sequence
- 查询Lucene
- ClassNotFoundException:org.hibernate.service.jndi.JndiException
- java.lang.ClassCastException:oracle.sql.CLOB无法强制转换为oracle.sql.CLOB
- 无法通过使用hibernate的存储过程获取多个Table实体
- HQL(Hibernate)如何检查元素列表是否是另一个列表的子集?
- 如何扫描Hibernate实体的包而不是使用hbm.xml?
- EclipseLinkJpaVendorAdapter而不是HibernateJpaVendorAdapter问题