2012-12-22 78 views
0

对不起,我的英语不好,可能是坏的问题。我有这样的:Sql jpa查询ManyToOne

实体

    @Entity 
        @Table(name = "Books") 
        @NamedQueries({ 
         @NamedQuery(name = "BooksEntity.findAll", query = "SELECT u FROM BooksEntity u"),  
         @NamedQuery(name = "BooksEntity.findByBookId", query = "SELECT u FROM BooksEntity u WHERE u.book_id = :book_id"), 
         @NamedQuery(name = "BooksEntity.findByTitle", query = "SELECT u FROM BooksEntity u WHERE u.title = :title")}) 
        public class BooksEntity implements Serializable { 
         private static final long serialVersionUID = 1L; 
         @Id 
         @Column(name = "book_id",unique=true, nullable=false) 
         @GeneratedValue(strategy = GenerationType.TABLE) 
         private Long book_id; 

         @ManyToOne 
         @JoinColumn(name = "author", nullable=true) 
         private AuthorsEntity author; 

         @OneToMany (mappedBy="book") 
         private List<UsersEntity> users; 
         //set and get 
        } 


       @Entity 
       @Table(name = "Users") 
       @NamedQueries({ 
        @NamedQuery(name = "UsersEntity.findAll", query = "SELECT u FROM UsersEntity u"),  
        @NamedQuery(name = "UsersEntity.findByUserId", query = "SELECT u FROM UsersEntity u WHERE u.user_id = :user_id"), 
        @NamedQuery(name = "UsersEntity.findByUserIdAndPassword", query = "SELECT u FROM UsersEntity u WHERE u.user_id = :user_id AND u.password = :password"), 
        @NamedQuery(name = "UsersEntity.findByName", query = "SELECT u FROM UsersEntity u WHERE u.name = :name"), 
        @NamedQuery(name = "UsersEntity.findByNameAndPassword", query = "SELECT u FROM UsersEntity u WHERE u.name = :name AND u.password = :password"), 
        @NamedQuery(name = "UsersEntity.findByEmail", query = "SELECT u FROM UsersEntity u WHERE u.email = :email")}) 
       public class UsersEntity implements Serializable { 

        private static final long serialVersionUID = 1L; 
        @Id 
        @Column(name = "user_id", unique=true, nullable=false) 
        @GeneratedValue(strategy = GenerationType.TABLE) 
        private Long user_id; 

        @Column(name = "name", nullable = false, unique = true) 
        private String name; 


        @ManyToOne 
        @JoinColumn(name = "book") 
        private BooksEntity book; 
       } 

和管理者

   @Stateless 
       public class BookManager implements BookManagerLocal { 

        @PersistenceContext 
        EntityManager em; 
        @EJB 
        UserManagerLocal um; 

      @Override 
       public List<BooksEntity> getAllBooks() { 
        List<BooksEntity> books = em.createNamedQuery("BooksEntity.findAll").getResultList(); 
        if (!books.isEmpty()) { 
         return books; 
        } else { 
         return null; 
        } 
       } 

       @Override 
        public List<BooksEntity> getAllBooksUser(String name) { 
        List<UsersEntity> users; 
         List<BooksEntity> books = this.getAllBooks(); 
         if (books.isEmpty()) { 
          return null; 
         } else { 
          List<BooksEntity> userbooks = new ArrayList<BooksEntity>(); 

          for (BooksEntity book : books) { 
           users = book.getUsers(); 
           for (UsersEntity user : users) { 
            if (name.equals(user.getName())) { 
             userbooks.add(book); 
            } 
           } 
          } 

          if (!userbooks.isEmpty()) { 
           return userbooks; 
          } else { 
           return null; 
          } 
         } 
        } 
       } 

我需要拥有所有书籍为一个用户。但我有问题。我做 这样

@Override 
     public List<BooksEntity> getAllBooks() { 
      List<BooksEntity> books = em.createNamedQuery("BooksEntity.findAll").getResultList(); 
      if (!books.isEmpty()) { 
       return books; 
      } else { 
       return null; 
      } 
     } 

    @Override 
     public List<BooksEntity> getAllBooksUser(String name) { 
     List<UsersEntity> users; 
      List<BooksEntity> books = this.getAllBooks(); 
      if (books.isEmpty()) { 
       return null; 
      } else { 
       List<BooksEntity> userbooks = new ArrayList<BooksEntity>(); 

       for (BooksEntity book : books) { 
        users = book.getUsers(); 
        for (UsersEntity user : users) { 
         if (name.equals(user.getName())) { 
          userbooks.add(book); 
         } 
        } 
       } 

       if (!userbooks.isEmpty()) { 
        return userbooks; 
       } else { 
        return null; 
       } 
      } 
     } 

但它不工作。我有ejbexception和nullpointexception。

WARNING: EJB5184:A system exception occurred during an invocation on EJB BookManager, method: public java.util.List book.ejb.BookManager.getAllBooksUser(java.lang.String) 
    WARNING: javax.ejb.EJBException 
     at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5215) 
     at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5113) 
     at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901) 
     at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045) 
     at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994) 
     at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222) 
     at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89) 
     at $Proxy230.getAllBooksUser(Unknown Source) 
     at book.bean.BookEditBean.getUserBooks(BookEditBean.java:52) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at javax.el.BeanELResolver.getValue(BeanELResolver.java:363) 
     at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) 
     at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) 
     at com.sun.el.parser.AstValue.getValue(AstValue.java:138) 
     at com.sun.el.parser.AstValue.getValue(AstValue.java:183) 
     at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224) 
     at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50) 
     at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) 
     at com.sun.faces.facelets.component.UIRepeat.getValue(UIRepeat.java:273) 
     at com.sun.faces.facelets.component.UIRepeat.getDataModel(UIRepeat.java:249) 
     at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:443) 
     at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:482) 
     at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:984) 
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757) 
     at javax.faces.render.Renderer.encodeChildren(Renderer.java:168) 
     at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845) 
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757) 
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760) 
     at javax.faces.render.Renderer.encodeChildren(Renderer.java:168) 
     at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845) 
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757) 
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760) 
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760) 
     at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402) 
     at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131) 
     at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288) 
     at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121) 
     at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
     at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) 
     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) 
     at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
     at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
     at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) 
     at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
     at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 
     at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 
     at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) 
     at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 
     at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 
     at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) 
     at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
     at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
     at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
     at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
     at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
     at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
     at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
     at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
     at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
     at java.lang.Thread.run(Thread.java:722) 
    Caused by: java.lang.NullPointerException 
     at book.ejb.BookManager.getAllBooksUser(BookManager.java:87) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052) 
     at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124) 
     at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388) 
     at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619) 
     at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) 
     at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571) 
     at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:42) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861) 
     at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) 
     at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571) 
     at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162) 
     at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861) 
     at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) 
     at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370) 
     at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360) 
     at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348) 
     at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214) 
     ... 61 more 

你能帮助我吗?感谢你的所有。

回答

2

您正在使用一种不好的做法,并且通过使用它,您会直接受到影响。返回List(或任何类型的集合)的方法不应该返回null。它应该返回一个空列表,如果没有什么可返回的话。通过返回空,你强迫每个来电者,包括你自己,总是检查null使用返回的列表,你没有这样做之前:

List<BooksEntity> books = this.getAllBooks(); 
if (books.isEmpty()) { 
    return null; 
} 

在上面的代码,你不检查,如果books为null然后致电isEmpty()。并且由于getAllBooks()在没有找到书籍的情况下返回null而不是空列表,您将得到NullPointerException。

这是我会怎么重写代码:

@Override 
public List<BooksEntity> getAllBooks() { 
    return em.createNamedQuery("BooksEntity.findAll").getResultList(); 
} 

@Override 
public List<BooksEntity> getAllBooksUser(String name) { 
    List<BooksEntity> books = this.getAllBooks(); 
    List<BooksEntity> userbooks = new ArrayList<BooksEntity>(); 
    for (BooksEntity book : books) { 
     users = book.getUsers(); 
     for (UsersEntity user : users) { 
      if (name.equals(user.getName())) { 
       userbooks.add(book); 
      } 
     } 
    } 
    return userBooks; 
} 

注意代码是如何更短,以及它如何没有抛出一个NullPointerException异常的风险。

也就是说,您为给定的用户名找到书的方法效率极低:您正在加载每本书(想象一下真正的图书馆),并且为每本书加载所有用户。

找到具有给定名称的所有用户(例如使用findByName命名查询)并返回他们的书会更有效率。甚至更好,做这一切在一个单一的JPQL查询:

select book from UsersEntity user 
inner join user.book book 
where user.name = :name 

然后,该方法是这样的:

public List<BooksEntity> getAllBooksUser(String name) { 
    String jpql = 
     "select book from UsersEntity user" 
     + " inner join user.book book" 
     + " where user.name = :name"; 
    return em.createTypedQuery(jpql, BooksEntity.class) 
      .setParameter("name", name) 
      .getResultList(); 
} 

最后,如果你命名你的实体您的代码将更具可读性BookUser,而不是BooksEntityUsersEntity。对单个用户或书使用复数形式是一个非常糟糕的主意。后缀Entity是烦人的噪音。

+0

非常感谢,我只学了2个月的java,这是我的第一个项目/ – hardor