2012-12-22 76 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