[Java EE JSF] Problem z pobraniem wartości z selectOneMenu

0

Witam, mam mały problem i liczę na pomoc forumowiczów :)

Mianowicie, mam dwie klasy, bean'y i ich managery, tak jak to przystało.
Są to: Book oraz Author, klasy są w relacji OneToMany-ManyToOne (autor ma wiele książek, książka ma jednego autora).

Teraz, poprzez formularz dodawania książki zależy mi na tym, aby z drop-down listy autorów przekazać id wybranego z nich. I tu pojawia się problem.

Oto skrócony kod formularza:

<h:form>
      <h:panelGrid columns="2">
      	                 	
        	<h:selectOneMenu id="pickAuthor" value="#{authorBean.allAuthors}">
        	<f:convertNumber type="number" />
  		   <f:selectItems value="#{authorBean.allAuthors}" var="author" 
  					itemValue="#{author.id}" 
  					itemLabel="#{author.surname} #{author.name}"/>
		</h:selectOneMenu>        	        	        
        	
        	<h:commandButton 
        		id="submit"
        		value="Dodaj ksiażkę!"
          		action="#{bookBean.addBook(form.pickAuthor.Value)}" />
      </h:panelGrid>      
    </h:form>

Wydaje mi się, że coś źle przekazuje w selectOneMenu.
Ale nie wiem co i ciężko mi do tego dojść.

0

Czy naprawdę nikt nie wie? Dla zaawansowanych nie powinno być to problemem jak na moje oko :)
Proszę o pomoc, dodatkowo dopowiem, że otrzymuję id autora, jednak z błędem:

Cannot convert 1 of type class java.lang.Long to interface java.util.List

W tym komunikacie liczba jest dokładnie wartością id autora o co mi chodziło, jednako taki błąd nie pozwala mi na dalszą pracę.
z góry dzięki!

0

Ja tak się zapytam badawczo: czy coś takiego
"#{bookBean.addBook(form.pickAuthor.Value)}"
czyli przekazanie argumetu w EL w JSF to w ogóle jest dopuszczalne? Normalnie używam Seam i tam coś takiego to norma, ale nie przypominam sobie tej konstrukcji z JSF. Ale mogę mieć słabą pamięć :)

0

Wydaje mi się, że tak, skoro wartość jest przekazana, tylko nie można jej skonwertować według informacji o wyjątku :)

0

Daj cały wyjątek i do tego linię kodu, która go rzuca (jak jesteś w stanie to ustalić).

0

Cały kod błędu:

 HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: javax.el.ELException: /addBook.xhtml @21,76 value="#{authorBean.allAuthors}": Cannot convert 1 of type class java.lang.Long to interface java.util.List
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:321)
	org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)
root cause

javax.faces.component.UpdateModelException: javax.el.ELException: /addBook.xhtml @21,76 value="#{authorBean.allAuthors}": Cannot convert 1 of type class java.lang.Long to interface java.util.List
	javax.faces.component.UIInput.updateModel(UIInput.java:848)
	javax.faces.component.UIInput.processUpdates(UIInput.java:730)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIForm.processUpdates(UIForm.java:268)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1218)
	com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:74)
	com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
	com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
	org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)
root cause

javax.el.ELException: /addBook.xhtml @21,76 value="#{authorBean.allAuthors}": Cannot convert 1 of type class java.lang.Long to interface java.util.List
	com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:136)
	javax.faces.component.UIInput.updateModel(UIInput.java:813)
	javax.faces.component.UIInput.processUpdates(UIInput.java:730)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIForm.processUpdates(UIForm.java:268)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1218)
	com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:74)
	com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
	com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
	org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)
note The full stack trace of the root cause is available in the JBoss Web/3.0.0-CR1 logs.

JBoss Web/3.0.0-CR1 

Linijka która go powoduje to:

    	***<h:selectOneMenu id="pickAuthor" value="#{authorBean.allAuthors}">***

wraz z:

    	**<h:commandButton id="submit" value="Dodaj ksiażkę!" action="#{bookBean.addBook(form.pickAuthor.Value)}" />**
0

To pokaż kod do authorBean, a przynajmniej metodę getAllAuthors. Z błędu wynika, że to tam jest problem.

0

Ok, już pokazuję, dzięki za chęć pomocy :)

AuthorBean:

 public List<Author> getAllAuthors(){
		return authorManager.getAllAuthors();
	} 

i manager,
AuthorManager:

 public List<Author> getAllAuthors(){
		return entityManager.createNamedQuery("author.all").getResultList();
	} 
0

To jest źle: <h:selectOneMenu id="pickAuthor" value="#{authorBean.allAuthors}">
To value tutaj to ma być zmienna w beanie, która się ustawi wartością itemValue="#{author.id}" z <f:selectItems, a tymczasem jest listą. Dodaj zmienną long selectedAuthor, dopisz geter i seter i tą wstaw w value.

0

Niestety,

exception

javax.servlet.ServletException: javax.ejb.EJBException: javax.persistence.NoResultException: No entity found for query
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:321)
	org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)

Dodałem:

private long selectedAuthorId;
+ publiczne setter i getter
0
chodnik napisał(a)

Ja tak się zapytam badawczo: czy coś takiego
"#{bookBean.addBook(form.pickAuthor.Value)}"
czyli przekazanie argumetu w EL w JSF to w ogóle jest dopuszczalne? Normalnie używam Seam i tam coś takiego to norma, ale nie przypominam sobie tej konstrukcji z JSF. Ale mogę mieć słabą pamięć :)

Tak jak piszesz, to jest coś co też od razu zwróciło moją uwagę. Nie pisałem w JSF jakiś czas ale w jego czystej wersji to raczej nie jest możliwe http://blogs.nuxeo.com/dev/2007/09/how-to-invoke-method-expressions-with-parameters-in-jsf.html. Lepiej przekaż id wybranego autora jako parametr. Służą do tego np takie tagi http://www.roseindia.net/jsf/param.shtml

0

Natomiast w sprawie Twojego błędu to na pewno źle jest to że używasz do wyświetliania List<Autor>. Tag h:selectOneMenu wymaga by przekazano mu List<SelectItem> http://jlaskowski.blogspot.com/2007/10/konwertery-w-javaserver-faces-cz-3.html

0

Udało mi się uporać z problemem w ten sposób:

W BookBeanie dopisałem pole selectedAuthorId typu long, poprzez które przekazuje id autora do metody dodającej.
Banalna sprawa, a jednak może namącić w głowie :)

BookBean:

 

private long selectedAuthorId;
	
	public String addBook(){
		bookManager.addBook(title, content, coverSrc, selectedAuthorId);
		return "Book added succesfully.";
	} 

Widok:

 <h:selectOneMenu id="pickAuthor" value="#{bookBean.selectedAuthorId}">
                <f:convertNumber type="number" />
                     <f:selectItems value="#{authorBean.allAuthors}" var="author" 
                                    itemValue="#{author.id}" itemLabel="#{author.surname} #{author.name}"/>
            </h:selectOneMenu>

<h:commandButton 
        		id="submit"
        		value="Dodaj nowego BOOKA!"
          		action="#{bookBean.addBook}" />   

 

Dziękuję wszystkim za odpowiedzi i pomoc! Temat do zamknięcia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1