jpa是什么?
JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行
JPA是需要Provider来实现其功能的,Hibernate就是JPA Provider中很强的一个,应该说无人能出其右。从功能上来说,JPA就是Hibernate功能的一个子集。Hibernate 从3.2开始,就开始兼容JPA。Hibernate3.2获得了Sun TCK的JPA(Java Persistence API) 兼容认证。
出现的问题
工作中使用了jpa来持久化数据,调试的时候抛了这样的异常No entity found for query,找不到查询的实体,导致这个问题主要是使用了getSingleResult()这个方法返回一个实体,下面我们看下源码找下原因
下面是getSingleResult实现源码
1@SuppressWarnings({ "unchecked", "RedundantCast" }) 2 public X getSingleResult() { 3 try { 4 final Listresult = query.list(); 5 6 if ( result.size() == 0 ) { 7 NoResultException nre = new NoResultException( "No entity found for query" ); 8 getEntityManager().handlePersistenceException( nre ); 9 throw nre; 10 } 11 else if ( result.size() > 1 ) { 12 final SetuniqueResult = new HashSet(result); 13 if ( uniqueResult.size() > 1 ) { 14 NonUniqueResultException nure = new NonUniqueResultException( "result returns more than one elements" ); 15 getEntityManager().handlePersistenceException( nure ); 16 throw nure; 17 } 18 else { 19 return uniqueResult.iterator().next(); 20 } 21 } 22 else { 23 return result.get( 0 ); 24 } 25 } 26 catch (QueryExecutionRequestException he) { 27 throw new IllegalStateException(he); 28 } 29 catch( TypeMismatchException e ) { 30 throw new IllegalArgumentException(e); 31 } 32 catch (HibernateException he) { 33 throw getEntityManager().convert( he ); 34 } 35 }
分析解决问题
从源码实现中的if判断我们可以看到,如果你使用了getSingleResult()来返回实体,结果为0或者大于1都会抛出异常。除非你能肯定你查询的实体存在且只有一个,不然一般返回实体还是建议使用getResultList()取结果集,然后做相关处理,如:
1Listlist=entityManager().createQuery("SELECT o FROM User o where o.userId=?1", User.class) 2 .setParameter(1, userId) 3 .getResultList(); 4 if(list!=null && list.size()!=0){ 5 return list.get(0); 6 } 7 return null ;
先判断结果集大小,根据结果集大小再确定是返回null还是取第一条
本文同步分享在 博客“kailing”(other)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。