问题
When I am clicking the Speak Out(p:commandButton) to submit a status, I am getting the following exception. The exception is caused by commentList() function by the line
Query query = em.createQuery(
"SELECT c FROM Comment c WHERE c.statusId=" + statusId,
Comment.class);
1)Home.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
</h:head>
<div style="width: 100%; background-color: #EEEEEE;">
<h:panelGrid columns="1">
<h:form id="speakout">
<h:outputText value="Speak Out" />
<br />
<h:outputText value="Share whats in your mind.!"
style="color:#aaaaaa;font-size:x-small;" />
<p:inputTextarea name="content" id="sharetext" cols="60" rows="2"
onclick="this.value='';" value="#{statusBean.status.statusmsg}"
style="text-size:small;" />
<br />
<p:commandButton type="submit" value="Speak Out"
action="#{statusBean.save}" ajax="false"
styleClass="buttonstyle" />
<br />
</h:form>
</div>
<!-- -->
<div class="items">
<h:form>
<ui:repeat var="p" value="#{statusBean.statusList}">
<ui:fragment rendered="#{p.statusmsg!=null}">
<div class="status">
<!-- for text status msg check-->
<h:commandLink action="#{friendBean.gotoFriendProfile(p.email)}"
styleClass="link">
<img src="../images/profilePicture/thumb/#{p.picture}"
style="height: 39px; width: 39px;" />
<h:outputText value="#{p.statusBy}:" />
</h:commandLink>
<h:outputText value="#{p.statusmsg}" styleClass="textstyle1" />
<h:outputText value="#{p.timeMillis}"
style="font-size:xx-small;float:right;color:#bbbbbb;font-style: italic;">
<f:converter converterId="timeConverter" />
</h:outputText>
<h:commandLink action="#{statusBean.deleteStatus(p.statusId)}"
value="Delete"></h:commandLink>
<p:growl />
<br />
<ui:repeat var="q" value="#{statusBean.commentList(p.statusId)}" >
<div class="barcomment">
<br />
<h:commandLink action="#{friendBean.gotoFriendProfile(q.email)}"
styleClass="link">
<img src="../images/profilePicture/thumb/#{q.picture}"
style="height: 29px; width: 29px;" />
<h:outputText value="#{q.commentBy}:" />
</h:commandLink>
<h:outputText value=" #{q.comment}" styleClass="textstyle1" />
<h:outputText value="#{q.timeMillis}"
style="font-size:xx-small;float:right;font-style: italic;">
<f:converter converterId="timeConverter" />
</h:outputText>
<h:commandLink action="#{statusBean.deleteComment(q.commentId)}"
value="Delete"></h:commandLink>
</div>
</ui:repeat>
<br />
<div class="comment">
<p:inputText value="#{statusBean.comment.comment}"
styleClass="box" />
<p:commandLink value="Views"
action="#{statusBean.update(p.statusId)}"
ajax="false" styleClass="link" />
</div>
<br />
</div>
</ui:fragment>
</ui:repeat>
</h:form>
</div>
</h:body>
</html>
2) Status Bean
package com.bean;
public class StatusBean {
Date d;
Comment comment;
Status status;
private EntityManager em;
private UploadedFile uploadedFile;
public Comment getComment() {
return comment;
}
public void setComment(Comment comment) {
this.comment = comment;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public StatusBean() {
d = new Date();
comment = new Comment();
status = new Status();
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("FreeBird");
em = emf.createEntityManager();
}
public List<Status> getStatusList() {
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext()
.getSession(true);
User user = (User) session.getAttribute("userdet");
Query query = em.createQuery("SELECT s FROM Status s WHERE s.email='"
+ user.getEmail() + "' ORDER BY s.timeMillis desc",
Status.class);
List<Status> results = query.getResultList();
Query query1 = em.createQuery("SELECT f FROM Friend f WHERE f.email='"
+ user.getEmail() + "'", Friend.class);
List<Friend> results1 = query1.getResultList();
Iterator<Friend> it = results1.listIterator();
while (it.hasNext()) {
String email = it.next().getFriendEmail();
Query query2 = em.createQuery(
"SELECT s FROM Status s WHERE s.email='" + email
+ "' ORDER BY s.timeMillis desc", Status.class);
List<Status> results2 = query2.getResultList();
results.addAll(results2);
}
Collections.sort(results);
int index = 0;
int end = index+5 > results.size() ? results.size() : index+5;
List<Status> subList = results.subList(0, end);
session.setAttribute("statusindex", end);
return subList;
}
public String save() {
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext()
.getSession(false);
User user = (User) session.getAttribute("userdet");
status.setEmail(user.getEmail());
status.setStatusBy(user.getFirstName());
d = new Date();
status.setTimeMillis(d.getTime());
status.setPicture(user.getImage());
System.out.println("status save called");
em.getTransaction().begin();
em.persist(status);
em.getTransaction().commit();
FacesContext context2 = FacesContext.getCurrentInstance();
context2.getExternalContext().getSessionMap().remove("statusBean");
return "success";
}
public String update(String statusId) {
System.out.println("Update Called...");
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext()
.getSession(true);
User user = (User) session.getAttribute("userdet");
comment.setStatusId(Integer.parseInt(statusId));
comment.setCommentBy(user.getFirstName());
comment.setPicture(user.getImage());
comment.setEmail(user.getEmail());
d = new Date();
comment.setTimeMillis(d.getTime());
em.getTransaction().begin();
em.persist(comment);
em.getTransaction().commit();
getComment().setComment("");
FacesContext context2 = FacesContext.getCurrentInstance();
context2.getExternalContext().getSessionMap().remove("statusBean");
return "success";
}
public List<Comment> commentList(String statusId) {
FacesContext context = FacesContext.getCurrentInstance();
Query query = em.createQuery(
"SELECT c FROM Comment c WHERE c.statusId=" + statusId,
Comment.class);
List<Comment> results = query.getResultList();
return results;
}
public String deleteStatus(String statusId) {
Status status = em.find(Status.class, Integer.parseInt(statusId));
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext()
.getSession(true);
User user = (User) session.getAttribute("userdet");
if (user.getEmail().equals(status.getEmail())) {
em.getTransaction().begin();
em.remove(status);
em.getTransaction().commit();
} else {
context.addMessage(null, new FacesMessage(
"You don't have permission to delete"));
}
return "success";
}
public String deleteComment(String commentId) {
Comment comment = em.find(Comment.class, Integer.parseInt(commentId));
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext()
.getSession(true);
User user = (User) session.getAttribute("userdet");
Status status = em.find(Status.class, comment.getStatusId());
if (user.getEmail().equals(status.getEmail())
|| comment.getEmail().equals(user.getEmail()))
{
em.getTransaction().begin();
em.remove(comment);
em.getTransaction().commit();
} else {
context.addMessage(null, new FacesMessage(
"You don't have permission to delete"));
}
return "success";
}
}
3)Exception
Mar 03, 2013 9:10:26 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Faces Servlet] in context with path [/FreeBird_v.6] threw exception [An exception occurred while creating a query in EntityManager:
Exception Description: Syntax error parsing the query [SELECT c FROM Comment c WHERE c.statusId=], line 0, column -1: unexpected end of query.
Internal Exception: NoViableAltException(-1@[792:1: comparisonExpressionRightOperand returns [Object node] : (n= arithmeticExpression | n= nonArithmeticScalarExpression | n= anyOrAllExpression );])] with root cause
NoViableAltException(-1@[792:1: comparisonExpressionRightOperand returns [Object node] : (n= arithmeticExpression | n= nonArithmeticScalarExpression | n= anyOrAllExpression );])
at org.eclipse.persistence.internal.libraries.antlr.runtime.DFA.noViableAlt(DFA.java:159)
at org.eclipse.persistence.internal.libraries.antlr.runtime.DFA.predict(DFA.java:144)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.comparisonExpressionRightOperand(JPQLParser.java:4326)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.comparisonExpression(JPQLParser.java:4215)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.simpleConditionalExpressionRemainder(JPQLParser.java:3389)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.simpleConditionalExpression(JPQLParser.java:3326)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.conditionalPrimary(JPQLParser.java:3275)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.conditionalFactor(JPQLParser.java:3194)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.conditionalTerm(JPQLParser.java:3103)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.conditionalExpression(JPQLParser.java:3029)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.whereClause(JPQLParser.java:2986)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.selectStatement(JPQLParser.java:380)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.document(JPQLParser.java:281)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.parse(JPQLParser.java:134)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.buildParseTree(JPQLParser.java:95)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:215)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:190)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:142)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:126)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1475)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1497)
at com.bean.StatusBean.commentList(StatusBean.java:227)
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.invoke(BeanELResolver.java:484)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:161)
at org.apache.el.parser.AstValue.getValue(AstValue.java:159)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:106)
at com.sun.faces.facelets.component.UIRepeat.getValue(UIRepeat.java:268)
at com.sun.faces.facelets.component.UIRepeat.getDataModel(UIRepeat.java:244)
at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:434)
at com.sun.faces.facelets.component.UIRepeat.doVisitChildren(UIRepeat.java:642)
at com.sun.faces.facelets.component.UIRepeat.visitTree(UIRepeat.java:600)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
at com.sun.faces.facelets.component.UIRepeat.visitTree(UIRepeat.java:606)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
at javax.faces.component.UIForm.visitTree(UIForm.java:331)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
at com.sun.faces.lifecycle.RestoreViewPhase.deliverPostRestoreStateEvent(RestoreViewPhase.java:258)
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:245)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:107)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
回答1:
It seems like p.statusId
which you are passing to commentList(String statusId)
is empty. You can try to put System.out.println("statusId: "+statusId);
to begining of commentList(String statusId)
method.
You can also put <h:outputText value="p.statusId: #{p.statusId}"/>
just before:
<ui:repeat var="q" value="#{statusBean.commentList(p.statusId)}" >
I'm also not sure if it's good practice to put statusBean.commentList(p.statusId)
in ui:repeat
value
attribute. You can end up retrieving list of Statuses from DB more often than you wanted to. It would be better to preload it to some property and then pass it where required.
UPDATE
Also replace:
Query query = em.createQuery(
"SELECT c FROM Comment c WHERE c.statusId=" + statusId, Comment.class);
with
TypedQuery<Comment> query = em.createQuery(
"SELECT c FROM Comment c WHERE c.statusId = :statusId", Comment.class);
query.setParameter("statusId", statusId);
This way your queries are safer against SQL injection and syntax errors.
UPDATE 2
private class StatusWrapper {
private Status status;
private List<Comment> comments;
}
In your StatusBean
...
private List<StatusWrapper> statuses;
...
(getters setters)
...
public StatusBean() {
...
initStatuses();
}
...
public void initStatuses() {
statuses=new ArrayList<>();
List<Status> stats=getStatusList();
for(Status status:stats) {
StatusWrapper wrapper=new StatusWrapper();
wraper.setStatus(status);
wraper.setComments(commentList(status.getStatusId()));
statuses.add(wrapper);
}
Than in your page just use statuses property. Hope it's clear (there are some typos probably.)
来源:https://stackoverflow.com/questions/15187480/status-update-not-working