am using jsf 2.0 + primefaces 3.2 + EJB 2.0 + JPA 2.0 .
hi everyone, when i try to affect a new student to a class the system raises an error message which is trasaction abored.
my entity code : ClasseHasEtudiant
public class ClasseHasEtudiant implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected ClasseHasEtudiantPK classeHasEtudiantPK;
#JoinColumn(name = "Etudiant_id", referencedColumnName = "id", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Etudiant etudiant;
#JoinColumn(name = "Classe_id", referencedColumnName = "id", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Classe classe;
public ClasseHasEtudiant() {
}
public ClasseHasEtudiant(ClasseHasEtudiantPK classeHasEtudiantPK) {
this.classeHasEtudiantPK = classeHasEtudiantPK;
}
public ClasseHasEtudiant(int classeid, int etudiantid) {
this.classeHasEtudiantPK = new ClasseHasEtudiantPK(classeid, etudiantid);
}
public ClasseHasEtudiantPK getClasseHasEtudiantPK() {
return classeHasEtudiantPK;
}
public void setClasseHasEtudiantPK(ClasseHasEtudiantPK classeHasEtudiantPK) {
this.classeHasEtudiantPK = classeHasEtudiantPK;
}
public Etudiant getEtudiant() {
return etudiant;
}
public void setEtudiant(Etudiant etudiant) {
this.etudiant = etudiant;
}
public Classe getClasse() {
return classe;
}
public void setClasse(Classe classe) {
this.classe = classe;
}
#Override
public int hashCode() {
int hash = 0;
hash += (classeHasEtudiantPK != null ? classeHasEtudiantPK.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof ClasseHasEtudiant)) {
return false;
}
ClasseHasEtudiant other = (ClasseHasEtudiant) object;
if ((this.classeHasEtudiantPK == null && other.classeHasEtudiantPK != null) || (this.classeHasEtudiantPK != null && !this.classeHasEtudiantPK.equals(other.classeHasEtudiantPK))) {
return false;
}
return true;
}
#Override
public String toString() {
return "dossierEtudiants.entities.ClasseHasEtudiant[ classeHasEtudiantPK=" + classeHasEtudiantPK + " ]";
}
}
code of entity ClasseHasEtudiantPK
#Embeddable
public class ClasseHasEtudiantPK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "Classe_id")
private int classeid;
#Basic(optional = false)
#NotNull
#Column(name = "Etudiant_id")
private int etudiantid;
public ClasseHasEtudiantPK() {
}
public ClasseHasEtudiantPK(int classeid, int etudiantid) {
this.classeid = classeid;
this.etudiantid = etudiantid;
}
public int getClasseid() {
return classeid;
}
public void setClasseid(int classeid) {
this.classeid = classeid;
}
public int getEtudiantid() {
return etudiantid;
}
public void setEtudiantid(int etudiantid) {
this.etudiantid = etudiantid;
}
#Override
public int hashCode() {
int hash = 0;
hash += (int) classeid;
hash += (int) etudiantid;
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof ClasseHasEtudiantPK)) {
return false;
}
ClasseHasEtudiantPK other = (ClasseHasEtudiantPK) object;
if (this.classeid != other.classeid) {
return false;
}
if (this.etudiantid != other.etudiantid) {
return false;
}
return true;
}
#Override
public String toString() {
return "dossierEtudiants.entities.ClasseHasEtudiantPK[ classeid=" + classeid + ", etudiantid=" + etudiantid + " ]";
}
}
this is my .xhtml code :
<ui:define name="content">
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="#{bundle.CreateClasseHasEtudiantLabel_etudiant}" for="etudiant" />
<h:selectOneMenu id="etudiant" value="#{classeHasEtudiantController.selected.etudiant}" title="#{bundle.CreateClasseHasEtudiantTitle_etudiant}" required="true" requiredMessage="#{bundle.CreateClasseHasEtudiantRequiredMessage_etudiant}">
<f:selectItems value="#{etudiantController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>
<h:outputLabel value="#{bundle.CreateClasseHasEtudiantLabel_classe}" for="classe" />
<h:selectOneMenu id="classe" value="#{classeHasEtudiantController.selected.classe}" title="#{bundle.CreateClasseHasEtudiantTitle_classe}" required="true" requiredMessage="#{bundle.CreateClasseHasEtudiantRequiredMessage_classe}">
<f:selectItems value="#{classeController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>
</h:panelGrid>
<br />
<h:commandLink action="#{classeHasEtudiantController.create}" value="#{bundle.CreateClasseHasEtudiantSaveLink}" />
<br />
<br />
<h:commandLink action="#{classeHasEtudiantController.prepareList}" value="#{bundle.CreateClasseHasEtudiantShowAllLink}" immediate="true"/>
<br />
<br />
<h:commandLink value="#{bundle.CreateClasseHasEtudiantIndexLink}" action="/index" immediate="true" />
</h:form>
</ui:define>
and this is my managedBean code :
public String prepareCreate() {
current = new ClasseHasEtudiant();
current.setClasseHasEtudiantPK(new dossierEtudiants.entities.ClasseHasEtudiantPK());
selectedItemIndex = -1;
return "Create";
}
public String create() {
try {
getFacade().create(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle1").getString("ClasseHasEtudiantCreated"));
return prepareCreate();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle1").getString("PersistenceErrorOccured"));
return null;
}
}
and finaly my log :
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`isetdb`.`classe_has_etudiant`, CONSTRAINT `classe_has_etudiant_ibfk_1` FOREIGN KEY (`Classe_id`) REFERENCES `classe` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
Error Code: 1452
Call: INSERT INTO classe_has_etudiant (Classe_id, Etudiant_id) VALUES (?, ?)
bind => [2 parameters bound]
Query: InsertObjectQuery(entities.ClasseHasEtudiant[ classeHasEtudiantPK=entities.ClasseHasEtudiantPK[ classeid=0, etudiantid=0 ] ])
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:840)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1702)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:253)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:342)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:162)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:177)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:472)
at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:287)
at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:829)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:728)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2863)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1501)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1483)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1443)
at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:224)
at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:123)
at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3784)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1407)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:634)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1497)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3135)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:344)
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:157)
at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:435)
at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:852)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5114)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4879)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2039)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1990)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at $Proxy302.create(Unknown Source)
at sessionBeans.__EJB31_Generated__ClasseHasEtudiantFacade__Intf____Bean__.create(Unknown Source)
at managedBeans.ClasseHasEtudiantController.create(ClasseHasEtudiantController.java:86)
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.el.parser.AstValue.invoke(AstValue.java:234)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:43)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:56)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
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 com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
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: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`isetdb`.`classe_has_etudiant`, CONSTRAINT `classe_has_etudiant_ibfk_1` FOREIGN KEY (`Classe_id`) REFERENCES `classe` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.Util.getInstance(Util.java:384)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3566)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3498)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2409)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2327)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2312)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:831)
... 87 more
Your database schema suggest that Classe_id is a foreign key.
But while saving class you are assigning a new Primary key which basically sets classeid and etudiantid to zero, and while saving record there are no records with matching id.
Current Implementation:
current.setClasseHasEtudiantPK(new dossierEtudiants.entities.ClasseHasEtudiantPK());
Instead you should set the id of Class and id of Student between which you are doing the mapping.
Looking from the xhtml I think in your managed bean you would be having something like
selected.classe which holds the selected class and selected.etudiant which holds the selected, so your code should look something like this:
ClasseHasEtudiantPK classeHasEtudiantPK = new dossierEtudiants.entities.ClasseHasEtudiantPK(selected.classe.classeid, selected.etudiant.etudiantid);
//Note depending upon your code the above two values selected.classe.classeid and selected.etudiant.etudinatid may change, so set according to your code.
current.setClasseHasEtudiantPK(classeHasEtudiantPK);
Related
I'm trying to develop a program using Primefaces that downloads all the images in a given URL. I've already successfully downloaded and it works fine but i need to add a functionality wherein i need to see the progress of all files being downloaded. Each file must have it's own progress bar. Also, one of the problems is having to create dynamic progress bars based on the files downloaded.
This is what i've come up so far.
#ManagedBean
public class CheckValidUrl {
private static final String FOLDERPATH = "C:/Users/jan.louise.h.casas/Downloads/";
private static final String IMAGE_PATTERN = "([^\\s]+(\\.(?i)(jpg|png|jpeg|ico|bmp))$)";
private Pattern pattern;
private Matcher matcher;
private String url;
private Integer progress;
private static boolean progressBarRendered;
private List<String> imagesList = new ArrayList<String>();
public List<String> getImagesList() {
return imagesList;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Integer getProgress() {
return progress;
}
public void setProgress(Integer progress) {
this.progress = progress;
}
public boolean isProgressBarRendered() {
return progressBarRendered;
}
public void cancel(){
progress = null;
}
public void onComplete() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Progress Completed"));
}
public void validateUrl() throws IOException {
UrlValidator urlValidator = new UrlValidator();
if(!urlValidator.isValid(url)){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Please make sure URL is valid"));
} else{
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Info", "Please wait"));
downloadImages();
}
}
public void downloadImages(){
try{
Document doc = Jsoup.connect(url).get();
Elements img = doc.getElementsByTag("img");
if(img.size() > 0){
for (Element el : img) {
String src = el.absUrl("src");
System.out.println("Image Found!");
System.out.println("src attribute is : "+src);
pattern = Pattern.compile(IMAGE_PATTERN);
if(validateImageType(src)){
imagesList.add(src);
}
}
if(!imagesList.isEmpty()){
getImages(imagesList);
} else{
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Warning", "URL only has GIFs"));
}
} else{
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Warning", "URL doesn't have any images"));
}
} catch(FileNotFoundException ex){
System.err.println("There was an error");
Logger.getLogger(CheckValidUrl.class.getName()).log(Level.SEVERE, null, ex);
} catch(IOException ex){
System.err.println("There was an error");
Logger.getLogger(CheckValidUrl.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static void getImages(List<String> imageSources) throws FileNotFoundException, IOException {
for(String src : imageSources){
int indexname = src.lastIndexOf("/");
if (indexname == src.length()) {
src = src.substring(1, indexname);
}
indexname = src.lastIndexOf("/");
String name = src.substring(indexname, src.length());
System.out.println(name);
URL url = new URL(src);
InputStream in = url.openStream();
OutputStream out = new BufferedOutputStream(new FileOutputStream( FOLDERPATH+ name));
for (int b; (b = in.read()) != -1;) {
progressBarRendered = true;
out.write(b);
System.out.println("Downloaded image: "+src);
System.out.println("Boolean Value: "+progressBarRendered);
}
out.close();
in.close();
}
}
public boolean validateImageType(String image){
pattern = Pattern.compile(IMAGE_PATTERN);
matcher = pattern.matcher(image);
return matcher.matches();
}
}
and in my check_valid_url.xhtml
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
<h:panelGrid columns="3" cellpadding="5">
<p:outputLabel for="url" value="Url:" />
<p:inputText id="url" value="#{checkValidUrl.url}" required="true" label="Url" />
<p:message for="url" display="icon" />
<p:commandButton value="Submit" update="progressBarPanel" actionListener="#{checkValidUrl.validateUrl}" onclick="PF('pbAjax').start()" icon="ui-icon-check" />
</h:panelGrid>
<h:panelGrid id="progressBarPanel">
<p:progressBar widgetVar="pbAjax" ajax="true" rendered="#{checkValidUr.progressBarRendered}" value="#{checkValidUrl.progress}" labelTemplate="{value}%" styleClass="animated" global="false">
<p:ajax event="complete" listener="#{checkValidUrl.onComplete}" update="panel"/>
</p:progressBar>
</h:panelGrid>
</p:panel>
</h:form>
I have a list of governorates that I displayed in a <p:selectOneMenu>
the java code in the managed bean:
public List<SelectItem> gouvernorats() {
List<Gouvernorat> all = emetteursEJB.findAllGouvernorat();
List<SelectItem> items = new ArrayList<>();
for (Gouvernorat g : all) {
items.add(new SelectItem(g, g.getLibelleGouv()));
}
return items;
}
in the <p:selectOneMenu> I add <p:ajax>:
<p:selectOneMenu value="#{emetteurBean.selectedGouvernorat}" style="width:160px" >
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{emetteurBean.gouvernorats()}" />
<p:ajax event="change" listener="#{emetteursBean.handelGouvChanged()"/>
</p:selectOneMenu>
in the method handelGouvChanged() selectedGouvernorat object is always null;
Recently I added the convert I stumbled upon NullPointerException
#FacesConverter(forClass = Gouvernorat.class)
public class EmetteursConverter implements Converter {
#EJB
private ReferentielDaoLocal refEJB;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String selectedValue) {
System.out.println("Inside The Converter");
System.out.println(selectedValue.length());
if (selectedValue == null) {
return null;
} else {
return refEJB.findGouvByCode(selectedValue.trim());
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return null;
} else {
return String.valueOf(((Gouvernorat) value).getIdGouvernorat());
}
}
}
I found a solution, I injected EJB with InitilContext.lookup ()
#FacesConverter(forClass = Gouvernorat.class)
public class GouvernoratConverter implements Converter {
private static final Logger LOG = Logger.getLogger(GouvernoratConverter.class.getName());
#Override
public Object getAsObject(FacesContext context, UIComponent component, String selectedValue) {
if (selectedValue == null) {
return null;
} else {
try {
ReferentielDaoLocal myService = (ReferentielDaoLocal) new
InitialContext().lookup("java:global/ErpCCF/ErpCCF-ejb/ReferentielDaoImpl");
return myService.findGouvByCode(selectedValue);
} catch (NamingException ex) {
LOG.log(Level.SEVERE, "Converter Gouvernorat Error", ex.getMessage());
return null;
}
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return null;
} else {
return String.valueOf(((Gouvernorat) value).getIdGouvernorat());
}
}
}
I filled my rightList of the PickList with Objects from a web service, but when i select some elements, i want to get these elements in myManagedBean, because i'll affect them to an Object.
JSF :
<h:form>
<rich:panel>
<h:panelGrid columns="2" styleClass="criteresSaisie"
rowClasses="critereLigne" columnClasses="titreColonne,">
<h:outputLabel for="libelleCoplement" value=" "
size="20" />
<rich:pickList d="libelleCoplement" sourceCaption="Compléments"
targetCaption="Compléments sélectionnés"
value="#{listeCmpltDispoModel.listeCmpltSelect}" size="15"
addText=">" addAllText=">>" removeText="<"
removeAllText="<<" listWidth="270px" listHeight="110px"
orderable="true">
<f:converter converterId="cmpltsTitresConcerter" />
<f:selectItems value="#{listeCmpltDispoModel.listeCmpltDispo}"
var="liste" itemLabel="#{liste.libelleComplement}"
itemValue="#{liste.cdComplement}"/>
</rich:pickList>
</h:panelGrid>
<h:panelGroup>
<div align="right">
<h:panelGrid columns="8">
<h:commandButton value="Valider"
action="#{saisieCmpltsTitreCtrl.valider}" />
</h:panelGrid>
</div>
</h:panelGroup>
</rich:panel>
</h:form>
The bean :
#ManagedBean(name = "listeCmpltDispoModel")
#SessionScoped
public class ListeCmpltDispoModel implements Serializable {
private static final long serialVersionUID = 1L;
private Long cdComplement;
private String libelleComplement;
private int nbCompl;
private List<ComplementsDispoSortieDTO> listeCmpltDispo ;
private List<ComplementsDispoSortieDTO> listeCmpltSelect ;
public ListeCmpltDispoModel() {
}
public Long getCodeComplement() {
return cdComplement;
}
public void setCodeComplement(Long cdComplement) {
this.cdComplement = cdComplement;
}
public String getLibelleComplement1() {
return libelleComplement;
}
public void setLibelleComplement1(String libelleCoplement) {
this.libelleComplement = libelleCoplement;
}
public Long getCdComplement() {
return cdComplement;
}
public void setCdComplement(Long cdComplement) {
this.cdComplement = cdComplement;
}
public String getLibelleComplement() {
return libelleComplement;
}
public void setLibelleComplement(String libelleComplement) {
this.libelleComplement = libelleComplement;
}
public List<ComplementsDispoSortieDTO> getListeCmpltDispo() {
return listeCmpltDispo;
}
public void setListeCmpltDispo(List<ComplementsDispoSortieDTO> listeCmpltDispo) {
this.listeCmpltDispo = listeCmpltDispo;
}
public int getNbCompl() {
return nbCompl;
}
public void setNbCompl(int nbCompl) {
this.nbCompl = nbCompl;
}
public List<ComplementsDispoSortieDTO> getListeCmpltSelect() {
return listeCmpltSelect;
}
public void setListeCmpltSelect(List<ComplementsDispoSortieDTO> listeCmpltSelect) {
this.listeCmpltSelect = listeCmpltSelect;
}
}
Converter :
#FacesConverter(value="cmpltsTitresConcerter")
public class CmpltsTitresConcerter implements Converter {
#SuppressWarnings("null")
public Object getAsObject(FacesContext context, UIComponent component,
String value){
ComplementsDispoSortieDTO cmpltSelect = null;
cmpltSelect.setCdComplement(Long.parseLong(value));
return cmpltSelect;
}
public String getAsString(FacesContext arg0, UIComponent arg1, Object obj) {
return String.valueOf(((ComplementsDispoSortieDTO) obj).getCdComplement());
}
}
Any help is greatly apprectiated!
Roughtly you need 3 things :
Custom converter for your object (Object to String, String to Object)
Getter/Setter with the List of your Objects choices
Getter/Setter with the List of your Objects selected
Everything is perfectly described here : RichFaces Showcase - pickList
EDIT :
Adding this should fix your problem :
<rich:pickList ...>
<f:converter converterId="cmpltsTitresConcerter" />
</rich:pickList>
also the converter property in <f:selectItems /> is not valid : f:selectItems
EDIT :
You should modify your converter like that to remove converting exceptions :
#FacesConverter(value="cmpltsTitresConcerter")
public class CmpltsTitresConcerter implements Converter
{
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
ComplementsDispoSortieDTO cmpltSelect = null;
if(value != null)
{
cmpltSelect = new ComplementsDispoSortieDTO();
cmpltSelect.setCdComplement(Long.parseLong(value));
}
return cmpltSelect;
}
public String getAsString(FacesContext arg0, UIComponent arg1, Object obj)
{
String result = null;
if(obj != null)
{
result = String.valueOf(((ComplementsDispoSortieDTO) obj).getCdComplement());
}
return result;
}
}
Your selected objects are bound to the value attribute which must have a getter and setter.
I've got a simple composite component which has to render a inputText. When a put the value and press commandButton the follow exception is throw:
java.lang.IllegalArgumentException: Cannot convert 1 of type class java.lang.String to class sample.entity.Product
When i use h:inputText instead d:myInputText it's work fine.
Is possible use a FacesConverter and attribute forClass for composite component? I do not like to use converter attribute or converterId of tag f:converter.
Anybody help me?
Page code:
<h:form>
<h:messages />
Product Id: <h:myInputText value="#{productController.product}"/>
<h:commandButton value="Submit" action="#{productController.someAction()}" />
Product Description: <h:outputText value="#{productController.product.description}"/>
</h:form>
Composite code:
<composite:interface>
<composite:attribute name="value"/>
<composite:editableValueHolder name="value" targets="#{cc.clientId}:value"/>
</composite:interface>
<composite:implementation>
<div id="#{cc.clientId}">
<h:inputText id="value" value="#{cc.attrs.value}"/>
<h:message for="#{cc.clientId}:value" />
</div>
</composite:implementation>
ManagedBean code:
#Named("productController")
#RequestScoped
public class ProductController {
private Product product;
public Product getProduct() {
if (product == null) {
product = new Product();
}
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public void someAction() {
System.out.println("Product " + product);
}
}
Converter code:
#FacesConverter(forClass = Product.class)
public class ProductConverter implements Converter {
#Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
System.out.println("[DEBUG] getAsObject: " + value);
if (value == null || "".equals(value)) {
return null;
}
//TODO: some logic to get entity from database.
return new Product(new Long(value));
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object o) {
System.out.println("[DEBUG] getAsString: " + o);
if (o == null) {
return null;
}
return String.valueOf(((Product) o).getId());
}
}
Entity code:
public class Product {
private Long id;
private String description;
public Product() {
}
public Product(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Product other = (Product) obj;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "Product{" + "id=" + id + '}';
}
}
I use Mojarra 2.1.14, Glassfish 3.1 and CDI.
Best regards.
I was able to reproduce it in Mojarra 2.1.14. This is a bug in Mojarra. It works fine in MyFaces 2.1.9. I've reported it to Mojarra guys as issue 2568. In the meanwhile, there's not really another option than explicitly specifying a <f:converter for> in the client or moving to MyFaces (which has its own set of specific quirks/issues as well though).
I'm still trying to program an app with jsf2, ejb3.1, cdi and glassfish.
I have a form which have a selectOneMenu
<h:form prependId="false">
...
<f:validateBean>
...
<h:selectOneMenu value="#{bottleManagedBean.selectProducer}" id="selectproducerb"
validatorMessage="#{messages.bottleaddinvalideproducer}" immediate="true">
<f:converter binding="#{producerConverter}"/>
<f:selectItems value="#{bottleManagedBean.producerItems}" />
</h:selectOneMenu>
...
The of the selectItems component are well showned but when I submit the form the value of bottleManagedBean.selectProducer is always null.
My formbean
#Named("bottleManagedBean")
#RequestScoped
public class BottleManagedBean {
....
private List<Producer> producers;
public List<Producer> getProducers() {
if (producers == null) {
setProducers(producerService.list(Producer.class));
}
return producers;
}
public void setProducers(List<Producer> producers) {
this.producers = producers;
}
private Producer selectProducer;
public Producer getSelectProducer() {
return selectProducer;
}
private List<SelectItem> producerItems;
public List<SelectItem> getProducerItems() {
if (producerItems == null) {
producerItems = new ArrayList<SelectItem>();
for (Producer current : getProducers()) {
producerItems.add(new SelectItem(current.getId(), current.getName()));
}
}
return producerItems;
}
public void setProducerItems(List<SelectItem> producerItems) {
this.producerItems = producerItems;
}
...
The converter
#Named("producerConverter")
public class ProducerConverter implements Converter {
#Inject
BusinessService<Producer> service;
private static Logger trace = Logger.getLogger(ProducerConverter.class.getCanonicalName());
#Override
public Object getAsObject(FacesContext fc, UIComponent uic, String id) {
try {
return service.findByID(Producer.class, Integer.parseInt(id));
} catch (NumberFormatException e) {
e.printStackTrace();
throw new ConverterException(e);
}
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object o) {
String asString = null;
if (o != null) {
asString = String.valueOf(o);
}
return asString;
}
}
I tried to debug the app .When I submit the form , the application never goes to the setter.
I also tried to add a valuechangelistener and my app never called this method.
Finally, I tried to submit an integer (eg. the id of my bean) and the value is well filled when I submit.1
So,... what's wrong ?
Thanks in advance for your help
here is how you should use the valuechangelistener properly in jsf2
Add <f:ajax listener="#{bottleManagedBean.selectProducer}" /> to your <h:selectOneMenu
Like this:
<h:selectOneMenu value="#{bottleManagedBean.selectProducerValueChange}" id="selectproducerb"
validatorMessage="#{messages.bottleaddinvalideproducer}">
<f:ajax listener="#{bottleManagedBean.selectProducerValueChange}" />
<f:converter binding="#{producerConverter}"/>
<f:selectItems value="#{bottleManagedBean.producerItems}" />
</h:selectOneMenu>
and implement the selectProducerValueChange in your bean...