Question

sorry for my bad english and may be bad question. I have this:

Entity

                    @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;
                }

And manager

                @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;
                            }
                        }
                    }
                }

I need have all books for one user. But i have problem with it. I do so

    @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;
                }
            }
        }

But it does not work. i have ejbexception and 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

Can you help me? Thanks for all you.

Was it helpful?

Solution

You're using a bad practice, and by using it, you're directly affected. A method returning a List (or any kind of collection), should never return null. It should return an empty list if there's nothing to return. By returning null, you force every caller, including yourself, to always check for null before using the returned list, which you failed to do:

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

In the above code, you don't check if books is null before calling isEmpty(). And since getAllBooks() returns null instead of an empty list in case no book is found, you get a NullPointerException.

Here's how I would rewrite your code:

@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;
}

Note how the code is much shorter, and how it doesn't have a risk of throwing a NullPointerException.

That said, your method of finding the books for a given user name is extremely inefficient: you're loading every book (imagine doing that with a real library), and for every book, you're loading all its users.

It would be much more efficient to find all the users with the given name (using the findByName named query, for example), and return their book. Or even better, to do all this in a single JPQL query:

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

The method would then look like this:

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();
}

Finally, your code would be more readable if you named your entities Book and User, instead of BooksEntity and UsersEntity. Using the plural form for a single user or book is a really bad idea. And the Entity suffix is annoying noise.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top