How to send Data from selectManyCheckbox to bean? - primefaces

i have a Java EE setup with JSF and primefaces and i'm trying to generate a selection, based on the chosen entry in a <selectOneMenu>.
My problem is that the selectManyCheckbox (or any other similar ui element) has all items filled in correctly and the items are selectable, but if a selection was made, the action of the commandButton doesn't get called.
I've set a breakpoint on the method. If I don't choose any item, the breakpoint gets hit, if I choose any amount of items greater than zero, the breakpoint doesn't get hit.
I read that one solution could be to define a converter. I tried that and if I set a breakpoint, it correctly converts the items, I chose, but nevertheless the method, defined as action, doesn't get called.
Btw: Sorry for german code, i'm a german and naming the methods and variables in german was set by guideline
The xhtml File:
<h:form>
<p:panelGrid columns="2">
<p:outputLabel for="kennzeichenInput">Kennzeichen: </p:outputLabel>
<p:inputText id="kennzeichenInput"></p:inputText>
<p:outputLabel for="studiengang">Studiengang: </p:outputLabel>
<p:selectOneMenu id="studiengang" value="#{registrationsController.gewaehlterStudiengang}">
<f:selectItem itemValue="#{null}" itemLabel="--Studiengang aussuchen--"/>
<f:selectItems value="#{registrationsController.getAlleStudiengaenge()}"/>
<p:ajax value="valueChange" update="vorlesungenInStudiengang" listener="#{registrationsController.onStudiengangGeaendert}"/>
</p:selectOneMenu>
</p:panelGrid>
<h:selectManyCheckbox id="vorlesungenInStudiengang"
value="#{registrationsController.gewaehlteVorlesungen}"
label="Vorlesungen" converter="de.phwt.parkhwt.domain.converter.vorlesung_converter">
<f:selectItems value="#{registrationsController.vorlesungen}"/>
</h:selectManyCheckbox >
<p:commandButton value="Registrieren" type="submit" action="#{registrationsController.registriereKennzeichen()}"/>
</h:form>
The Bean:
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.enterprise.context.RequestScoped;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Inject;
import javax.inject.Named;
import de.phwt.parkhwt.domain.CollectionKonverter;
import de.phwt.parkhwt.domain.KennzeichenRepository;
import de.phwt.parkhwt.domain.Studiengang;
import de.phwt.parkhwt.domain.Vorlesung;
#RequestScoped
#Named
public class RegistrationsController
{
#Inject
private KennzeichenRepository repository;
private String gewaehlterStudiengang;
private List<Vorlesung> vorlesungen;
private List<Vorlesung> gewaehlteVorlesungen;
public String getGewaehlterStudiengang()
{
return gewaehlterStudiengang;
}
public void setGewaehlterStudiengang(String gewaehlterStudiengang)
{
this.gewaehlterStudiengang = gewaehlterStudiengang;
}
public List<Vorlesung> getVorlesungen()
{
return vorlesungen;
}
public void setVorlesungen(List<Vorlesung> vorlesungen)
{
this.vorlesungen = vorlesungen;
}
public Vorlesung getVorlesung(String name)
{
return this.repository.sucheVorlesung(name);
}
public List<Vorlesung> getGewaehlteVorlesungen()
{
return gewaehlteVorlesungen;
}
public void setGewaehlteVorlesungen(List<Vorlesung> gewählteVorlesungen)
{
this.gewaehlteVorlesungen = gewählteVorlesungen;
}
public Set<Studiengang> getAlleStudiengaenge()
{
return repository.getAlleStudiengaenge();
}
public List<Vorlesung> getVorlesungenDesStudiengangs(String gewaehlterStudiengang)
{
Studiengang studiengang = repository.sucheStudiengang(gewaehlterStudiengang);
return CollectionKonverter.toList(studiengang.getVorlesungen());
}
public String registriereKennzeichen()
{
return "";
}
public void onStudiengangGeaendert(AjaxBehaviorEvent event)
{
if (getGewaehlterStudiengang() != null)
{
setVorlesungen(getVorlesungenDesStudiengangs(getGewaehlterStudiengang()));
}
else
{
setVorlesungen(new ArrayList<Vorlesung>());
}
}
}
The Converter:
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import de.phwt.parkhwt.controller.RegistrationsController;
#FacesConverter("de.phwt.parkhwt.domain.converter.vorlesung_converter")
public class VorlesungConverter implements Converter
{
#Inject
KennzeichenRepository repository;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
ValueExpression vex =
context.getApplication()
.getExpressionFactory()
.createValueExpression(context.getELContext(),
"#{registrationsController}", RegistrationsController.class);
RegistrationsController reg = (RegistrationsController) vex.getValue(context.getELContext());
Vorlesung vorlesung = reg.getVorlesung(value);
return vorlesung;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
if (value.getClass() == new Vorlesung().getClass())
{
Vorlesung v = (Vorlesung) value;
return v.getName();
}
return null;
}
}

Thanks to Mike Balthasar for his comment!
The solution was to add ajax="false" to my commandButton.
For more information, see his comment.

Related

Why does a row selection in a p:dataTable cause multiple update of rowdata?

For optimize the performance of an application I discovered an unexpected behavior in datatable during single row selection.
....
<p:dataTable
id="table"
var="object"
value="#{testBean.objects}"
rowKey="#{object.paramA}"
selectionMode="single"
selection="#{testBean.selectedObject}"
>
<p:ajax
event="rowSelect"
process="#this"
/>
....
If i select a row the getters for all columns of all entries in table are called. Why does it behave like these?
And are they options to disable these?
I tried to use different process like '#none' but these also disable the setter for the selectionObject.
Thanks for any tips.
Edit:
In use Primeface 6.0; JSF 2.0; JavaSE 1.6;
Edit2:
executable Code
testpage.xhtml
<h:form id="form">
<p:dataTable
id="dtSelection"
var="object"
value="#{selectionTestBean.objects}"
selectionMode="single"
selection="#{selectionTestBean.selectedObject}"
rowKey="#{object.variableA}"
>
<p:ajax
event="rowSelect"
/>
<p:column headerText="Variable">
<h:outputText value="#{object.variableA}" />
</p:column>
</p:dataTable>
</h:form>
Bean
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;
#WebSessionBean
#Named("selectionTestBean")
public class SelectionTestBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<ObjectA> objects;
private ObjectA selectedObject;
#PostConstruct
private void init() {
System.out.println("PostConstruct Bean");
this.objects = new ArrayList<ObjectA>();
for(int i=0; i<20; i++) {
ObjectA object = new ObjectA(i);
this.objects.add(object);
}
}
public List<ObjectA> getObjects() {
System.out.println("getObjects");
return this.objects;
}
public ObjectA getSelectedObject() {
System.out.println("getSelectedObject");
return this.selectedObject;
}
public void setSelectedObject(ObjectA selectedObject) {
System.out.println("setSelectedObject");
this.selectedObject = selectedObject;
}
}
Object
public class ObjectA {
private int variableA;
public ObjectA(int variableA) {
this.variableA = variableA;
}
public int getVariableA() {
System.out.println("getVariableA:"+this.variableA);
return this.variableA;
}
public void setVariableA(int variableA) {
this.variableA = variableA;
}
}
Output
// Step 1 load page
PostConstruct Bean
getSelectedObject
getObjects
getSelectedObject
getObjects
getVariableA:0
getVariableA:0
getVariableA:1
getVariableA:1
getVariableA:2
getVariableA:2
getVariableA:3
getVariableA:3
getVariableA:4
getVariableA:4
getVariableA:5
getVariableA:5
getVariableA:6
getVariableA:6
getVariableA:7
getVariableA:7
getVariableA:8
getVariableA:8
getVariableA:9
getVariableA:9
getVariableA:10
getVariableA:10
getVariableA:11
getVariableA:11
getVariableA:12
getVariableA:12
getVariableA:13
getVariableA:13
getVariableA:14
getVariableA:14
getVariableA:15
getVariableA:15
getVariableA:16
getVariableA:16
getVariableA:17
getVariableA:17
getVariableA:18
getVariableA:18
getVariableA:19
getVariableA:19
//---
//Step 2 click on row
getObjects
getObjects
getObjects
getObjects
getObjects
getVariableA:0
getVariableA:1
getVariableA:2
getVariableA:3
getVariableA:4
getVariableA:5
getVariableA:6
getVariableA:7
getVariableA:8
getVariableA:9
getVariableA:10
getVariableA:11
getVariableA:12
getVariableA:13
getVariableA:14
getVariableA:15
getVariableA:16
getVariableA:17
getVariableA:18
getVariableA:19
getObjects
getVariableA:0
getVariableA:1
getVariableA:2
getVariableA:3
getVariableA:4
getVariableA:5
getVariableA:6
getVariableA:7
getVariableA:8
getVariableA:9
getVariableA:10
getVariableA:11
getVariableA:12
getVariableA:13
getVariableA:14
getVariableA:15
getVariableA:16
getVariableA:17
getVariableA:18
getVariableA:19
getObjects
getObjects
getObjects
getObjects
getObjects
getObjects
getObjects
setSelectedObject
getObjects
getObjects
getObjects
//---
Like you can see in Output the selection cause the getter of each object in the table. Why? And are they options to prevent these?

JasperReports Passing Parameters

I have a report in JasperReports, it works fine. However, i'm passing just one parameter of type cliente to the report, and what i do want now is to pass more than one. The page is like in the picture bellow, a basic idea was to have a button (maybe) that would send the content of <p:selectOneMenu that is of the type cliente each time its clicked to the map of parameters, than it would be sent to the report. I wasn't able to do that yet, so i'm asking for a help.
Bean:
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import org.hibernate.Session;
import com.rodrigo.controleacidentes.model.Cliente;
import com.rodrigo.controleacidentes.model.StatusEntrada;
import com.rodrigo.controleacidentes.util.jsf.FacesUtil;
import com.rodrigo.controleacidentes.util.report.ExecutorRelatorioPdf;
import com.rodrigo.controleacidentes.util.report.ExecutorRelatorioXls;
#Named
#RequestScoped
public class RelatorioEntradasBean implements Serializable {
private static final long serialVersionUID = 1L;
private Date dataInicio;
private Date dataFim;
private Cliente cliente;
private StatusEntrada statusEntrada;
public StatusEntrada getStatusEntrada() {
return statusEntrada;
}
public void setStatusEntrada(StatusEntrada statusEntrada) {
this.statusEntrada = statusEntrada;
}
public void teste(StatusEntrada st) {
// StatusEntrada entrada = StatusEntrada.valueOf(st);
System.out.println("TESTE: " + st);
}
#Inject
private FacesContext facesContext;
#Inject
private HttpServletResponse response;
#Inject
private EntityManager manager;
public void emitirXls() {
Map<String, Object> parametros = new HashMap<>();
parametros.put("data_inicio", this.dataInicio);
parametros.put("data_fim", this.dataFim);
if (cliente != null) {
System.out.println("TESTE: " + cliente.getNome());
parametros.put("nome_cliente", cliente.getNome());
}
if (statusEntrada != null) {
System.out.println("TESTE :" + statusEntrada.getDescricao());
parametros.put("status_entrada", statusEntrada.getDescricao());
}
ExecutorRelatorioXls executor = new ExecutorRelatorioXls("/relatorios/RelatorioEntradasNome.jasper",
this.response, parametros, "Relatório Entradas.xls");
Session session = manager.unwrap(Session.class);
session.doWork(executor);
if (executor.isRelatorioGerado()) {
facesContext.responseComplete();
} else {
FacesUtil.addErrorMessage("A execução do relatório não retornou dados.");
}
}
public void emitirPdf() {
Map<String, Object> parametros = new HashMap<>();
parametros.put("data_inicio", this.dataInicio);
parametros.put("data_fim", this.dataFim);
parametros.put("nome_cliente", this.cliente);
ExecutorRelatorioPdf executor = new ExecutorRelatorioPdf("/relatorios/RelatorioEntradasNome.jasper",
this.response, parametros, "Relatório Entradas.pdf");
Session session = manager.unwrap(Session.class);
session.doWork(executor);
if (executor.isRelatorioGerado()) {
facesContext.responseComplete();
} else {
FacesUtil.addErrorMessage("A execução do relatório não retornou dados.");
}
}
#NotNull
public Date getDataInicio() {
return dataInicio;
}
public void setDataInicio(Date dataInicio) {
this.dataInicio = dataInicio;
}
#NotNull
public Date getDataFim() {
return dataFim;
}
public void setDataFim(Date dataFim) {
this.dataFim = dataFim;
}
#NotNull
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
}
Executor:
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.jdbc.Work;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
public class ExecutorRelatorioXls implements Work {
private String caminhoRelatorio;
private HttpServletResponse response;
private Map<String, Object> parametros;
private String nomeArquivoSaida;
private boolean relatorioGerado;
public ExecutorRelatorioXls(String caminhoRelatorio, HttpServletResponse response, Map<String, Object> parametros,
String nomeArquivoSaida) {
this.caminhoRelatorio = caminhoRelatorio;
this.response = response;
this.parametros = parametros;
this.nomeArquivoSaida = nomeArquivoSaida;
this.parametros.put(JRParameter.REPORT_LOCALE, new Locale("pt", "BR"));
}
#Override
public void execute(Connection connection) throws SQLException {
try {
InputStream relatorioStream = this.getClass().getResourceAsStream(this.caminhoRelatorio);
JasperPrint print = JasperFillManager.fillReport(relatorioStream, this.parametros, connection);
this.relatorioGerado = print.getPages().size() > 0;
if (this.relatorioGerado) {
JRXlsExporter exportador = new JRXlsExporter();
exportador.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, response.getOutputStream());
exportador.setParameter(JRXlsExporterParameter.JASPER_PRINT, print);
exportador.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
exportador.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
exportador.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
response.setHeader("Content-Transfer-Encoding", "Cp1256");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=\"" + this.nomeArquivoSaida + "\"");
exportador.exportReport();
}
} catch (Exception e) {
throw new SQLException("Erro ao executar relatório " + this.caminhoRelatorio, e);
}
}
public boolean isRelatorioGerado() {
return relatorioGerado;
}
}
Query in the report:
SELECT DISTINCT
ocorrencia.`id` AS ocorrencia_id,
ocorrencia.`descricao` AS ocorrencia_descricao,
ocorrencia.`condicao_tempo` AS ocorrencia_condicao_tempo,
ocorrencia.`data_ocorrencia` AS ocorrencia_data_ocorrencia,
ocorrencia.`periodo_ocorrencia` AS ocorrencia_periodo_ocorrencia,
ocorrencia.`condutor_id` AS ocorrencia_condutor_id,
condutor.`id` AS condutor_id,
condutor.`codigo` AS condutor_codigo,
condutor.`nome` AS condutor_nome,
entrada_acidente.`id` AS entrada_acidente_id,
entrada_acidente.`data_criacao` AS entrada_acidente_data_criacao,
entrada_acidente.`ocorrencia_id` AS entrada_acidente_ocorrencia_id,
entrada_acidente.`valor_unitario` AS entrada_acidente_valor_unitario,
cliente.`id` AS cliente_id,
cliente.`nome` AS cliente_nome,
entrada_acidente.`status` AS entrada_acidente_status
FROM
`condutor` condutor INNER JOIN `ocorrencia` ocorrencia ON condutor.`id` = ocorrencia.`condutor_id`
INNER JOIN `entrada_acidente` entrada_acidente ON ocorrencia.`id` = entrada_acidente.`ocorrencia_id`
INNER JOIN `cliente` cliente ON entrada_acidente.`cliente_id` = cliente.`id`
WHERE
entrada_acidente.`data_criacao` BETWEEN $P{data_inicio} AND $P{data_fim}
AND cliente.`nome` = $P{nome_cliente}
AND entrada_acidente.`status` = $P{status_entrada}
xhtml:
<ui:composition template="/WEB-INF/template/LayoutPadrao.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="titulo">Relatório de entradas emitidas</ui:define>
<ui:define name="corpo">
<h:form id="frm">
<h1>Relatório de entradas emitidas</h1>
<p:messages autoUpdate="true" closable="true" />
<p:toolbar style="margin-top: 20px">
<p:toolbarGroup>
<p:commandButton value="EmitirPdf"
action="#{relatorioEntradasBean.emitirPdf}" ajax="false" />
<p:commandButton value="EmitirXls"
action="#{relatorioEntradasBean.emitirXls}" ajax="false" />
</p:toolbarGroup>
</p:toolbar>
<p:panelGrid columns="7" id="painel"
style="width: 100%; margin-top: 20px" columnClasses="rotulo, campo">
<p:outputLabel value="Data de criação" />
<h:panelGroup>
<p:calendar value="#{relatorioEntradasBean.dataInicio}"
label="Data inicial" pattern="dd/MM/yyyy" size="8" />
<p:spacer width="8" />
<h:outputText value="a" />
<p:spacer width="8" />
<p:calendar value="#{relatorioEntradasBean.dataFim}"
label="Data final" pattern="dd/MM/yyyy" size="8" />
</h:panelGroup>
<h:panelGroup>
<p:outputLabel value="Cliente" for="cliente" />
<p:autoComplete id="cliente" size="40" dropdown="true"
value="#{relatorioEntradasBean.cliente}"
completeMethod="#{cadastroEntradaBean.completarCliente}"
var="cliente" itemLabel="#{cliente.nome}" itemValue="#{cliente}"
forceSelection="true" />
</h:panelGroup>
<p:outputLabel value="Status" />
<h:panelGroup>
<p:selectOneMenu id="statusEntrada"
value="#{relatorioEntradasBean.statusEntrada}">
<f:selectItem itemLabel="Selecione" />
<f:selectItems value="#{enumProviderStatus.statusEntradas}"
var="statusEntrada" itemValue="#{statusEntrada}"
itemLabel="#{statusEntrada.descricao}" />
</p:selectOneMenu>
</h:panelGroup>
</p:panelGrid>
</h:form>
</ui:define>
</ui:composition>

not able to savedata to mysql db, in gradle project, Neither BindingResult nor plain target object for bean name 'goal' available as request attribute

I was watching tutorial and i created user-login and verifying the user, when i created addGoal, my goal was not entering in my mysql database, since i am able to login so my database connection are correct, and i am using thymeleaf with javaconfig for my annotations, please help me with this i am new to this. I think there is error in my addGoal.html, as i am using thymeleaf i think i am not doing in correctly, please can someone help me to fix it, i think i am not handling #modelattribute correctly
Goal class is :
package com.pluralsight.model;
import hello.User;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.validator.constraints.Range;
import org.springframework.web.bind.annotation.ModelAttribute;
#Entity
#Table(name="goals")
public class Goal {
public static final String FIND_ALL_GOALS = "findALLGoals";
public static final String FIND_GOAL_REPORTS = "findGoalReports";
#Id
#GeneratedValue
#Column(name="GOAL_ID")
private Long id;
#Range(min = 1, max = 120)
#Column(name="MINUTES")
private int minutes;
// #OneToMany(mappedBy="goal",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
// private List<Exercise> exercises = new ArrayList<Exercise>();
#ManyToOne
#JoinColumn(name="USER_NAME")
private User user;
//
// public List<Exercise> getExercises() {
// return exercises;
// }
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Long getId() {
return id;
}
public int getMinutes() {
return minutes;
}
// public void setExercises(List<Exercise> exercises) {
// this.exercises = exercises;
// }
public void setId(Long id) {
this.id = id;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
}
This is my goalcontroller.java
package com.pluralsight.controller;
import java.util.List;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.pluralsight.model.Goal;
import com.pluralsight.model.GoalReport;
import com.pluralsight.model.User;
import com.pluralsight.service.GoalService;
#Controller
#SessionAttributes("goal")
public class GoalController {
#Autowired
private GoalService goalService;
#RequestMapping(value = "addGoal", method = RequestMethod.GET)
public String addGoal(Model model, HttpSession session ) {
//Goal goal = new Goal();
Goal goal = (Goal)session.getAttribute("goal");
if(goal == null){
goal = new Goal();
goal.setMinutes(10);
}
model.addAttribute("goal", goal);
return "addGoal";
}
#RequestMapping(value = "addGoal", method = RequestMethod.POST)
public String updateGoal(#Valid #ModelAttribute Goal goal, BindingResult result) {
System.out.println("result has errors: " + result.hasErrors());
System.out.println("Goal set: " + goal.getMinutes());
if(result.hasErrors()) {
return "addGoal";
}else{
goalService.save(goal);
}
return "redirect:index.jsp";
}
#RequestMapping(value="getGoals", method= RequestMethod.GET)
public String getGoals(Model model){
List<Goal> goals = goalService.findAllGoals();
model.addAttribute("goals", goals);
return "getGoals";
}
#RequestMapping(value="getGoalReports", method= RequestMethod.GET)
public String getGoalReports(Model model){
List<GoalReport> goalReports = goalService.findAllGoalReports();
model.addAttribute("goalReports", goalReports);
return "getGoalReports";
}
}
Here is my GoalRepository
package com.pluralsight.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.pluralsight.model.Goal;
#Repository("goalRepository")
public interface GoalRepository extends JpaRepository<Goal, Long>{
}
And here is my GoalServiceImpl.java
package com.pluralsight.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.pluralsight.model.Goal;
import com.pluralsight.model.GoalReport;
import com.pluralsight.repository.GoalRepository;
#Service("goalService")
public class GoalServiceImpl implements GoalService {
#Autowired
private GoalRepository goalRepository;
#Transactional
public Goal save(Goal goal) {
return goalRepository.save(goal);
}
public List<Goal> findAllGoals() {
return (List<Goal>) goalRepository.findAll();
}
public List<GoalReport> findAllGoalReports() {
return null;
// return goalRepository.findAllGoalReports();
}
}
And here is my addGoal.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
</head>
<body>
<div class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="#"> Add Goal </a>
<ul class="nav"></ul>
</div>
</div>
</div>
<div class="container">
<div>
<h1>Add Goal</h1>
<p>Add your workout goal in minutes for the day.</p>
</div>
<form th:action="#{/addGoal}" method="post">
<div>
<label> Enter Minutes : <input type="text" name="minutes" />
</label>
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
<div class="control-group"></div>
</div>
</body>
</html>
When i am changing my form in addGoal.html as
<form action="#" th:action="#{/addGoal}" th:object="${goal}" method="post">
<p> enter Minutes: <input type="text" th:field="*{goal.minutes}"/></p>
<p><input type="submit" value="enter goal minutes"/></p>
</form>
Then i am getting error as : Neither BindingResult nor plain target object for bean name 'goal' available as request attribute
Lets take a step back focus on restless state first.
For your form use this:
<form th:object="${goal}" th:action="#{/addGoal}" method="post">
<div>
<label> Enter Minutes : <input type="text" th:field="*{minutes}" />
</label>
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
Next change:
#RequestMapping(value = "addGoal", method = RequestMethod.GET)
public String addGoal(Model model, HttpSession session ) {
Goal goal = new Goal();
Goal sessionGoal = (Goal)session.getAttribute("goal");
if(sessionGoal == null && sessionGoal.getMinutes() == 0){
goal.setMinutes(10);
}
else {
goal.setMinutes(sessionGoal.getMinutes());
}
model.addAttribute("goal", goal);
return "addGoal";
}
Also you are doing return "redirect:index.jsp"; yet you are using Thymeleaf. This ain't going to work.
You need to "redirect:/index" or "redirect:/" depending on your home parameter.
EDIT 1:
change the following lines in your POST method of addGoal:
#RequestMapping(value = "addGoal", method = RequestMethod.POST)
public String updateGoal(#Valid #ModelAttribute("goal") Goal goal, BindingResult result) {

PrimeFaces datatable remove selectionMode attribute once set

I am trying to toggle between a simple "click the row to select" table and a "multi-select Checkbox in the first column table". I have a check box outside the table to change the state of the table. For the simple table (no check boxes in the first column) a selectionMode must be set in the p:datatable tag; either to "single" or "multiple". In this state everything works fine.
If the state is changed so that the multi-select column is rendered, the click event seems to be consumed by selecting the selecting the row. In general when using this multi-select check box table the selectionMode would not be set; hence the mouse event would change the state of the check box.
How do I "unset" the selectionMode. Here are the things that did not work:
table.setSelectionMode(null) - this breaks the selection (so does setting to "")
table.getAttributes().get("javax.faces.component.UIComponentBase.attributesThatAreSet") then removing the selectionMode (it isn't in the set attributes).
My xhtml looks like:
<h:form id="addForm">
<p:panel toggleable="false" closable="false" widgetVar="remarksPanel"
id="remarksPanel" style="margin-bottom:5px; overflow:auto;">
<p:selectBooleanCheckbox value="#{multipleSelectBean.bulkEdit}">
<p:ajax update="addForm:remarksTable"
listener="#{multipleSelectBean.editModeChanged}" />
</p:selectBooleanCheckbox>
<h:outputText value=" Bulk Edit" />
<p:dataTable var="remark" id="remarksTable" rowIndexVar="rowNum"
value="#{multipleSelectBean.remarkList}" rowKey="#{remark.id}"
selectionMode="multiple"
selection="#{multipleSelectBean.selectedRemarks}">
<p:column rendered="#{multipleSelectBean.bulkEdit}"
selectionMode="multiple" style="width:18px" />
<p:column headerText="Remark">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{remark.remark}" />
</f:facet>
<f:facet name="input">
<p:inputText style="width:98%" id="remark"
value="#{remark.remark}" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
My Bean Looks Like:
package gov.gsa.krichards.sandbox;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.event.SelectEvent;
#ManagedBean
#SessionScoped
public class MultipleSelectBean implements Serializable {
private static final long serialVersionUID = 1L;
private final static String[] categoryList;
private List<Remark> remarkList = new ArrayList<Remark>();
private Remark[] selectedRemarks = null;
private String words = "Mauris interdum, turpis nec euismod c aliquet fermentum nisl, in tristique arcu tincidunt nec.";
private boolean bulkEdit = false;
private boolean initialized = false;
static {
categoryList = new String[4];
categoryList[0] = "Cat5";
categoryList[1] = "Cat4";
categoryList[2] = "Cat3-UTP";
categoryList[3] = "BNC";
}
public MultipleSelectBean() {
Random r = new Random();
for (int i = 0; i < 10; i++) {
String cat = categoryList[r.nextInt(4)];
int len = words.length();
int begIndex = r.nextInt(len / 2);
int endIndex = begIndex + r.nextInt(len - begIndex);
Remark rem = new Remark(i, cat, words.substring(begIndex, endIndex));
remarkList.add(rem);
}
}
public void editModeChanged() {
System.out.println("changed to " + bulkEdit);
}
public void setBulkEdit(boolean arg) {
DataTable table = (DataTable) FacesContext.getCurrentInstance()
.getViewRoot().findComponent("addForm:remarksTable");
bulkEdit = arg;
if (bulkEdit) {
table.setSelectionMode("single");
} else {
table.setSelectionMode("multiple");
}
}
public boolean isBulkEdit() {
return bulkEdit;
}
public List<Remark> getRemarkList() {
return remarkList;
}
public void setRemarkList(List<Remark> remarkList) {
this.remarkList = remarkList;
}
public String[] getCategoryList() {
return categoryList;
}
public Remark[] getSelectedRemarks() {
if (selectedRemarks == null || selectedRemarks.length == 0)
return null;
return selectedRemarks;
}
public void setSelectedRemarks(Remark[] selectedRemarks) {
this.selectedRemarks = selectedRemarks;
}
}

Openejb rest integration tests with exception mappers

I'm writing some integration tests towards my jax-rs service where I have a set of exception mappers. So, when performing a given request I expect a certain response code based on the exception mapper. The problem is that I cannot get the exception mappers to be invoked when running in this environment.
My service which should throw a logicalexception in my test:
#Stateless
#Path("/baseCustomer")
public class BaseCustomerService {
#EJB //this one gets mocked in the unittest
private BaseCustomerManagerBean customerManager;
#POST
#Path("crud")
#Consumes({MediaType.APPLICATION_XML})
#Produces({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Hkunde createCustomer(Hkunde newCustomer) throws LogicalException {
//throws exception according to mocking
return customerManager.createCustomer(newCustomer);
}
And the exception mapper:
#Provider
public class LogicalExceptionMapper implements ExceptionMapper<LogicalException> {
#Override
public Response toResponse(LogicalException exception) {
return Response.status(Response.Status.FORBIDDEN).build();
}
}
I set up my tests like this:
#Mock
private BaseCustomerManagerBean baseCustomerManager;
private HttpClient httpClient;
private BaseCustomerServiceClient client;
#Configuration
public Properties config() throws Exception {
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, Boolean.TRUE.toString());
properties.setProperty(DeploymentFilterable.CLASSPATH_INCLUDE, LogicalExceptionMapper.class.getName());
properties.setProperty("openejb.jaxrs.providers.auto", "true");
properties.setProperty("openejb.servicemanager.enabled", "true");
return properties;
}
#MockInjector
public Class<?> mockitoInjector() {
return MockitoInjector.class;
}
#Module
public EjbModule createModule() throws Exception {
final StatelessBean bean = (StatelessBean) new StatelessBean(BaseCustomerService.class).localBean();
bean.setRestService(true);
final EjbJar ejbJar = new EjbJar();
ejbJar.addEnterpriseBean(bean);
final OpenejbJar openejbJar = new OpenejbJar();
openejbJar.addEjbDeployment(new EjbDeployment(ejbJar.getEnterpriseBeans()[0]));
EjbModule module = new EjbModule(ejbJar);
module.setOpenejbJar(openejbJar);
return module;
}
#Module
public Class[] exceptionMappers() {
return new Class[]{LogicalExceptionMapper.class};
}
#Before
public void setup() {
ServiceHost serviceHost = new ServiceHost("http://localhost:4204/BaseCustomerServiceTest");
httpClient = new HttpClient(serviceHost);
client = new BaseCustomerServiceClient(httpClient);
}
#Test
public void createCustomer_givenLogicalException_expectsLogicalException() throws LogicalException {
Hkunde expected = new Hkunde(true);
when(baseCustomerManager.createCustomer(expected)).thenThrow(new LogicalException("mock"));
try {
client.createCustomer(expected);
fail("Expected LogicalException");
} catch (LogicalException ex) {
}
verify(baseCustomerManager).createCustomer(expected);
}
So when I execute the test, my client will read the response code from the response and throw an exception based on this code.
The problem is that the exception mapper is never invoked, and I always receive a 500 internal server error, instead of the "forbidden" response. I'm guessing I need to add some more info when setting up the ejbjar or something like that.
Thanks!
This example http://svn.apache.org/repos/asf/openejb/trunk/openejb/examples/rest-applicationcomposer/src/test/java/org/superbiz/composed/rest/GreetingServiceTest.java (via http://rmannibucau.wordpress.com/2012/09/13/use-mockito-with-openejb/ ;-)) shows exactly what you want.
Add the following after openejbJar.addEjbDeployment(... and it should work.
final Properties properties = openejbJar.getEjbDeployment().iterator().next().getProperties();
properties.setProperty("cxf.jaxrs.providers", LogicalExceptionMapper.class.getName());
Here is a minimal working example (using openejb-cxf-rs 4.5.0 and openejb-core 4.5.0):
import java.util.Properties;
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.openejb.OpenEjbContainer;
import org.apache.openejb.config.EjbModule;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.StatelessBean;
import org.apache.openejb.jee.oejb3.EjbDeployment;
import org.apache.openejb.jee.oejb3.OpenejbJar;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.junit.Configuration;
import org.apache.openejb.junit.Module;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(ApplicationComposer.class)
public class RestWithExceptionMapper {
#Configuration
public Properties configuration() {
return new Properties() {
{
setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, Boolean.TRUE.toString());
}
};
}
#Module
public EjbModule app() {
final StatelessBean bean = (StatelessBean) new StatelessBean(MyResource.class).localBean();
bean.setRestService(true);
final EjbJar ejbJar = new EjbJar();
ejbJar.addEnterpriseBean(bean);
final OpenejbJar openejbJar = new OpenejbJar();
openejbJar.addEjbDeployment(new EjbDeployment(ejbJar.getEnterpriseBeans()[0]));
final Properties properties = openejbJar.getEjbDeployment().iterator().next().getProperties();
properties.setProperty("cxf.jaxrs.providers", MyExceptionMapper.class.getName());
final EjbModule module = new EjbModule(ejbJar);
module.setOpenejbJar(openejbJar);
return module;
}
public static class FooException extends RuntimeException {
}
public static class MyExceptionMapper implements ExceptionMapper<FooException> {
#Override
public Response toResponse(final FooException t) {
return Response.ok("Objection!").build();
}
}
#Path(value = "/test")
public static class MyResource {
#GET
#Path(value = "/throw")
public String throwException() {
throw new FooException();
}
}
#Test
public void checkServiceWasDeployed() {
assertEquals("Objection!", WebClient.create("http://localhost:4204/RestWithExceptionMapper").path("/test/throw").get(String.class));
}
}