抱歉我的英语不好,可能是个坏问题。我有这个:
实体
@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
你能帮帮我吗?谢谢大家。
答案 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();
}
最后,如果您将实体命名为Book
和User
,而不是BooksEntity
和UsersEntity
,那么您的代码将更具可读性。对单个用户或书使用复数形式是一个非常糟糕的主意。 Entity
后缀是恼人的噪音。