Sql jpa查询ManyToOne

时间:2012-12-22 19:47:15

标签: jpa nullpointerexception ejb isqlquery

  抱歉我的英语不好,可能是个坏问题。我有这个:

实体       

                    @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
  你能帮帮我吗?谢谢大家。

1 个答案:

答案 0 :(得分:2)

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

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

在上面的代码中,在调用books之前,您不会检查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后缀是恼人的噪音。