[RESOLVIDO] JSF 2.0 - Erro ao salvar view

edubiss, tentei as implementações conforme vc falou, mas nenhuma funcionou.

1º tentei usando o conversor padrão:

<h:selectManyListbox value="#{professorBean.professor.materias}" size="5">
				<f:selectItems value="#{materiaBean.lista}" var="var" itemLabel="#{var.materia}" itemValue="#{var.id}"/>
				<f:converter  converterId="javax.faces.Long"/>
			</h:selectManyListbox>

2º depois criei uma classe de conversão, seguindo seu código. Tentando definir essa classe na propriedade converterId dava erro dizendo que não conseguia localizar o conversor. Tentei implementar a tag @FacesConverter(forClass = Materia.class) na própria classe de conversão, mas também não adiantou.

Quando tento salvar, vem o mesmo erro:

21726 [http-8080-2] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.matrix.modelo.materia.Materia.id
	at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:62)
	at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:230)
	at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3852)
	at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3560)
	at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:204)
	at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243)
	at org.hibernate.type.EntityType.getIdentifier(EntityType.java:449)
	at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:132)
	at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:816)
	at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1204)
	at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:183)
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
	at com.matrix.web.filter.ConexaoHibernateFilter.doFilter(ConexaoHibernateFilter.java:30)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field com.matrix.modelo.materia.Materia.id to java.lang.String
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
	at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
	at sun.reflect.UnsafeObjectFieldAccessorImpl.get(Unknown Source)
	at java.lang.reflect.Field.get(Unknown Source)
	at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:59)
	... 31 more
Nov 22, 2012 4:02:39 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet Faces Servlet threw exception
javax.servlet.ServletException
	at com.matrix.web.filter.ConexaoHibernateFilter.doFilter(ConexaoHibernateFilter.java:40)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Unknown Source)

O que achei estranho é que, quando eu usei o conversor padrão, conforme descri no nº 1, o erro vinha descrito como :

Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field com.matrix.modelo.materia.Materia.id to java.lang.Long

Aí que eu não entendi mais nada. Alguma outra idéia do que possa resolver?

cnidhogg,

Bom, eu tenho uma outra ideia que deve funcionar. Tu pode mapear essa lista do h:selectManyListbox no teu Bean e não como objeto. Explico:

No Bean você teria uma lista de String (que é o que h:selectManyListbox espera).

private List<String> materiasSelecionadas = new ArrayList<String>();

Na tela tu mapearia isso no h:selectManyListbox.

<h:selectManyListbox value="#{professorBean.materiasSelecionadas}"> //resto do codigo sem o conversor

O detalhe é que na hora de salvar, tu terá que converter essa lista, para as materias do teu relacionamento.

for (String id : materiasSelecionadas) { Materia materia = new Materia(Long.valueOf(id)); professor.getMaterias().add(materia); } professorRN.salvar(professor);

Tenta dessa forma e vê se da certo…

edubiss,

Obrigado pela dica, tentei implementar aqui mas não estou conseguindo fazer o selectManyListbox carregar a lista de String, provavelmente ignorância minha.

Vamos lá:

  1. Sobrescreva o método toString() de Materia.

  2. Crie um conversor:

Veja este exemplo e tente adaptar ao seu projeto.

@FacesConverter(value = "materiaConverter", forClass = pacote.Materia.class)
public class MateriaConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        MateriaDAO materiaDAO = new MateriaDAO();
        Materia materia = null;
        if ((value != null) && (!value.equals(""))) {
            materia = materiaDAO.buscarPorId(new Long(value));
        }
        return materia;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        String retorno = "";
        if (!value.equals("")) {
            Materia materia = (Materia) value;
            if (!(materia.getId() == null)) {
                retorno = materia.getId().toString();
            }
        }
        return retorno;
    }
}

Adicione o conversor ao componente:

<h:selectManyListbox value="#{professorBean.professor.materias}" size="5" converter="materiaConverter">  
                <f:selectItems value="#{materiaBean.lista}" var="var" itemLabel="#{var.materia}" itemValue="#{var}"/>  
</h:selectManyListbox>  

Acredito que com isto funcionará.

benignoms, funcionou conforme sua dica!

Muito obrigado! Vlw a todos que tentaram me ajudar!