Fórum problema ao persistir entidade com campo tipo enum #383829

17/08/2010

0

opa td bom..
 
seguinte.. to fazendo uma app de cadastro de curriculo com hibernate e jsf mas to enroscado em uma parte do cadastro... a minha idéia é cadastrar idioma e nivel de conhecimanto usando enum.. então eu tenho a classe Idioma que possui nome e nivel (ambos tipo enum).. a classe Curriculo possui relacionamento one-to-many com a classe Idioma, pois um curriculo possui vários idiomas.. como a classe Idioma possui nome do idioma e nível de conhecimento.. a classe curriculo possui uma lista  de idiomas.. mas não estou conseguindo finalizar essa idéia.. vou postar os código e a msg de erro na sequencia:
 
hibernate xml da classe Idioma e Curriculo:
 
<hibernate-mapping>
    <typedef class="br.com.working.entity.StringEnumUserType" name="nivel">
        <param name="enumClassName">br.com.working.entity.Nivel</param>
    </typedef>
    <typedef class="br.com.working.entity.StringEnumUserType" name="nome">
        <param name="enumClassName">br.com.working.entity.Nome</param>
    </typedef>
    <class name="br.com.working.entity.Idioma" table="idioma">
        <id name="id" column="idioma">
            <generator class="sequence">
                <param name="sequence">idioma_seq</param>
            </generator>
        </id>
 
        <property name="nivel" column="nivel" type="nivel" not-null="true" update="false" access="field" />
        <property name="nome" column="nome" type="nome" not-null="true" update="false" access="field" />
        <many-to-one name="curriculo" class="br.com.working.entity.Curriculo" column="curriculo" />
    </class>
</hibernate-mapping>
 
<hibernate-mapping>
    <class name="br.com.working.entity.Curriculo" table="curriculo">
        <id name="id" column="pessoa">
            <generator class="foreign">
                <param name="property">pessoa</param>
            </generator>
        </id>
        <property name="objetivo" column="objetivo" />
        <one-to-one name="pessoa" class="br.com.working.entity.Pessoa" constrained="true" />
        <bag name="ep" cascade="all" inverse="true">
            <key column="curriculo" not-null="true" />
            <one-to-many class="br.com.working.entity.ExperienciaProfissional" />
        </bag>
        <bag name="fa" cascade="all" inverse="true">
            <key column="curriculo" not-null="true" />
            <one-to-many class="br.com.working.entity.FormacaoAcademica" />
        </bag>
        <bag name="idioma" cascade="all" inverse="true">
            <key column="curriculo" not-null="true" />
            <one-to-many class="br.com.working.entity.Idioma" />
        </bag>
    </class>
</hibernate-mapping>
 
 
trecho método do managed bean que prepara a página  
(aqui existe a classe Pessoa p que é dona do curriculo)
o nivel de idioma vem da página jsf:
 
    public String preparaCurriculo3 () {
        
        curriculo = curDao.getCurriculo(p.getCurriculo().getId());
        listIdioma = curDao.getIdioma(curriculo.getId());
        
        if (listIdioma.size() > 0)  
        {
            idioma1 = listIdioma.get(0);  
        }
        else {
            idioma1 = new Idioma();
            idioma1.setNome(Nome.INGLES);
        }
        
        if (listIdioma.size() > 1) {
            idioma2 = listIdioma.get(1);  
        }
        else {
            idioma2 = new Idioma();
            idioma2.setNome(Nome.ESPANHOL);
        }
        
        listIdioma.removeAll(listIdioma);
        listIdioma.add(idioma1);
        listIdioma.add(idioma2);
        
        idioma1.setCurriculo(curriculo);
        idioma2.setCurriculo(curriculo);
        curriculo.setIdioma(listIdioma);
 
        p.setCurriculo(curriculo);
        curriculo.setPessoa(p);
 
        return "addCurriculo3";
    }
 
quando vou salvar a página vem o seguinte erro:
 
org.hibernate.PropertyValueException: not-null property references a null or transient value: br.com.working.entity.Idioma.nivel
    at org.hibernate.engine.Nullability.checkNullability(Nullability.java:95)
 
alguém sabe o que está errado?
Fabiano Souza

Fabiano Souza

Responder

Posts

17/08/2010

Dyego Carmo

Opa !

Pelo que eu Estou vendo... a classe br.com.working.entity.Idioma até existe , porem a sua propriedade nivel (dentro de  br.com.working.entity.Idioma) está NULL , poderia confirmar ?(use um System.out.println(""))


Responder

Gostei + 0

18/08/2010

Fabiano Souza

coloquei a seguinte linha:

System.out.println(p.getCurriculo().getIdioma().get(1).getNivel());
e imprimiu: INTERMEDIARIO

desconfio que seja um erro no mapeamento ou o campo enum no banco.

eu to usando ORACLE e ae vai a pergunta: que tipo deve ser meu campo enum no oracle? eu coloquei VARCHAR2(255)
Responder

Gostei + 0

19/08/2010

Dyego Carmo

Opa , poderia colar as classes java aqui ? estou com duvidas...

Já tentou realizar este mapeamento utilizando anotações ? é até mais facil !

Responder

Gostei + 0

23/08/2010

Fabiano Souza

arquivo Curriculo do hibernate:
 
<hibernate-mapping>
    <class name="br.com.working.entity.Curriculo" table="curriculo">
        <id name="id" column="pessoa">
            <generator class="foreign">
                <param name="property">pessoa</param>
            </generator>
        </id>
        <property name="objetivo" column="objetivo" />
        <one-to-one name="pessoa" class="br.com.working.entity.Pessoa" constrained="true" />
        <bag name="ep" cascade="all" inverse="true">
            <key column="curriculo" not-null="true" />
            <one-to-many class="br.com.working.entity.ExperienciaProfissional" />
        </bag>
        <bag name="fa" cascade="all" inverse="true">
            <key column="curriculo" not-null="true" />
            <one-to-many class="br.com.working.entity.FormacaoAcademica" />
        </bag>
        <bag name="idioma" cascade="all" inverse="true">
            <key column="curriculo" not-null="true" />
            <one-to-many class="br.com.working.entity.Idioma" />
        </bag>
    </class>
</hibernate-mapping>
 
arquivo Idioma do hibernate:
 
<hibernate-mapping>
    <typedef class="br.com.working.entity.StringEnumUserType" name="nivel">
        <param name="enumClassName">br.com.working.entity.Nivel</param>
    </typedef>
    <typedef class="br.com.working.entity.StringEnumUserType" name="nome">
        <param name="enumClassName">br.com.working.entity.Nome</param>
    </typedef>
    <class name="br.com.working.entity.Idioma" table="idioma">
        <id name="id" column="idioma">
            <generator class="sequence">
                <param name="sequence">idioma_seq</param>
            </generator>
        </id>
 
        <property name="nivel" column="nivel" type="nivel" not-null="true" update="false" access="field" />
        <property name="nome" column="nome" type="nome" not-null="true" update="false" access="field" />
        <many-to-one name="curriculo" class="br.com.working.entity.Curriculo" column="curriculo" />
    </class>
</hibernate-mapping>
 
classes Java:
 
public class Curriculo implements Serializable{
 
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
     
    private Integer id;
    private String objetivo;
    private Pessoa pessoa;
    private List<ExperienciaProfissional> ep;
    private List<FormacaoAcademica> fa;
    private List<Idioma> idioma;
 
    // getters and setters equals and hashcode
}
 
public class Idioma implements Serializable{
 
    /**
     * 
     */
    private static final long serialVersionUID = 4942411828844125491L;
 
    /* member variables */
    private Integer id;
    private Curriculo curriculo;
    private Nome nome;
    private Nivel nivel;
 
    // getters and setters equals and hashcode
}
 
arquivos enum:
 
public enum Nivel {
    NENHUM(0), BASICO(1), INTERMEDIARIO(2), AVANCADO(3), FLUENTE(4);
     
    private Integer nivel;
     
    /* constructor */
    Nivel (Integer nivel) {
        this.nivel = nivel;
    }
 
    /* getters and setters */
    public Integer getNivel() {
        return nivel;
    }
}
 
public enum Nome {
    INGLES("Inglês"), 
    ESPANHOL("Espanhol");
     
     
    private String nome;
     
    /* constructor */
    Nome (String nome) {
        this.nome = nome;
    }
 
    /* getters and setters */
    public String getNome() {
        return nome;
    }
}
 
quando eu salvo o curriculo td dá certo eis o código:
 
    public static void main(String[] args) {     
 
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
         
        Pessoa p = new Pessoa();
        Curriculo curriculo = new Curriculo();
        Idioma idioma1 = new Idioma();
        Idioma idioma2 = new Idioma();
        Idioma idioma3 = new Idioma();
        List<Idioma> listIdioma = new ArrayList<Idioma>();
 
        p.setDtNascimento(new GregorianCalendar().getTime());
        p.setEstCivil("S");
        p.setNome("fabianoooooooooooooooooooooooooooooooooooooooooo");
        p.setSexo("M");
        p.setLocalNascimento("campinas");
        p.setCurriculo(curriculo);
 
        idioma1.setNivel(Nivel.AVANCADO);
        idioma1.setNome(Nome.INGLES);
        idioma1.setCurriculo(curriculo);
         
        idioma2.setNivel(Nivel.NENHUM);
        idioma2.setNome(Nome. ESPANHOL);
        idioma2.setCurriculo(curriculo);
         
        idioma3.setNivel(Nivel.FLUENTE);
        idioma3.setNome(Nome.INGLES);
        idioma3.setCurriculo(curriculo);
         
        listIdioma.add(idioma1);
        listIdioma.add(idioma2);
        listIdioma.add(idioma3);
         
        curriculo.setIdioma(listIdioma);
        curriculo.setObjetivo("teste");         
        curriculo.setPessoa(p);
         
        session.save(p);
         
        tx.commit();
        session.flush();
        session.close();
}
 
até aqui td funciona.. tô salvando os arquivos.. agora vou alterar e é onde dá o erro.
eis o código:
 
    public static void main(String[] args) {     
 
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
         
        PessoaDAO pDao = new PessoaDAO();
        CurriculoDAO cDao = new CurriculoDAO();
         
        Pessoa p = pDao.getPessoa(444);
        Curriculo curriculo = cDao.getCurriculo(444);
        Idioma idioma1 = new Idioma();
        Idioma idioma2 = new Idioma();
        Idioma idioma3 = new Idioma();
        List<Idioma> listIdioma = new ArrayList<Idioma>();
 
        p.setDtNascimento(new GregorianCalendar().getTime());
        p.setEstCivil("S");
        p.setNome("fabianoooooooooooooooooooooooooooooooooooooooooo");
        p.setSexo("M");
        p.setLocalNascimento("campinas");
        p.setCurriculo(curriculo);
 
        idioma1.setNivel(Nivel.AVANCADO);
        idioma1.setNome(Nome.INGLES);
        idioma1.setCurriculo(curriculo);
         
        idioma2.setNivel(Nivel.NENHUM);
        idioma2.setNome(Nome. ESPANHOL);
        idioma2.setCurriculo(curriculo);
         
        idioma3.setNivel(Nivel.FLUENTE);
        idioma3.setNome(Nome.INGLES);
        idioma3.setCurriculo(curriculo);
         
        listIdioma.add(idioma1);
        listIdioma.add(idioma2);
        listIdioma.add(idioma3);
         
        curriculo.setIdioma(listIdioma);
        curriculo.setObjetivo("teste");         
        curriculo.setPessoa(p);
         
        session.merge(p);
         
        tx.commit();
        session.flush();
        session.close();
}
 
eis o erro:
 
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: br.com.working.entity.Idioma.nivel
    at org.hibernate.engine.Nullability.checkNullability(Nullability.java:95)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
    at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:238)
    at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:170)
    at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:714)
    at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:696)
    at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:268)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
    at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:319)
    at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:265)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:242)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
    at org.hibernate.event.def.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:459)
    at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:318)
    at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:167)
    at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:714)
    at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:696)
    at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:268)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
    at org.hibernate.event.def.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:459)
    at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:318)
    at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:167)
    at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:81)
    at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:704)
    at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:688)
    at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:692)
    at br.com.working.test.Teste.main(Teste.java:77)
Responder

Gostei + 0

25/08/2010

Dyego Carmo

Opa !

Para alterar voce nao pode criar uma lista nova de idiomas e setar... para alterar voce deve RECUPERAR a lista que Já está salva e alterar os itens dentro dela...

TEste e me avise !

Responder

Gostei + 0

26/08/2010

Fabiano Souza

fiz a alteração que vc pediu.. agora não dá mais erro .. porêm, nenhuma alteração é feita.
algo ainda está errado taí o código:
 
    public static void main(String[] args) {     
     
 
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
         
        PessoaDAO pDao = new PessoaDAO();
        CurriculoDAO cDao = new CurriculoDAO();
         
        Pessoa p = pDao.getPessoa(444);
        Curriculo curriculo = cDao.getCurriculo(444);
        List<Idioma> listIdioma = cDao.getIdioma(curriculo.getId());
         
        p.setDtNascimento(new GregorianCalendar().getTime());
        p.setEstCivil("S");
        p.setNome("fabianoooooooooooooooooooooooooooooooooooooooooo");
        p.setSexo("M");
        p.setLocalNascimento("campinas");
        p.setCurriculo(curriculo);
 
        listIdioma.get(0).setNivel(Nivel.FLUENTE);
        listIdioma.get(0).setNome(Nome.INGLES);
        listIdioma.get(0).setCurriculo(curriculo);
         
        listIdioma.get(1).setNivel(Nivel.FLUENTE);
        listIdioma.get(1).setNome(Nome. ESPANHOL);
        listIdioma.get(1).setCurriculo(curriculo);
         
        listIdioma.get(2).setNivel(Nivel.FLUENTE);
        listIdioma.get(2).setNome(Nome.INGLES);
        listIdioma.get(2).setCurriculo(curriculo);
         
        curriculo.setIdioma(listIdioma);
        curriculo.setObjetivo("teste");         
        curriculo.setPessoa(p);
         
        session.merge(p);
         
        tx.commit();
        session.flush();
        session.close();
    }
Responder

Gostei + 0

26/08/2010

Dyego Carmo

Esses seus DAOS estão criando sessions dentro ?

Crie um construtor nestes daos e passe o session que vc instancia por primeiro para eles utilizarem , teste e me fale.

Responder

Gostei + 0

27/08/2010

Fabiano Souza

Não estou usando mais os daos.. e ainda não está salvando..

    public static void main(String[] args) {         
 
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
         
        Pessoa p = (Pessoa) session.get(Pessoa.class, 444);
        Curriculo curriculo = (Curriculo) session.get(Curriculo.class, p.getId());         
        List<Idioma> listIdioma = curriculo.getIdioma();
         
        p.setDtNascimento(new GregorianCalendar().getTime());
        p.setEstCivil("S");
        p.setNome("fabianoooooooooooooooooooooooooooooooooooooooooo");
        p.setSexo("M");
        p.setLocalNascimento("campinas");
        p.setCurriculo(curriculo);
 
        listIdioma.get(0).setNivel(Nivel.FLUENTE);
        listIdioma.get(0).setNome(Nome.INGLES);
        listIdioma.get(0).setCurriculo(curriculo);
         
        listIdioma.get(1).setNivel(Nivel.FLUENTE);
        listIdioma.get(1).setNome(Nome. ESPANHOL);
        listIdioma.get(1).setCurriculo(curriculo);
         
        listIdioma.get(2).setNivel(Nivel.FLUENTE);
        listIdioma.get(2).setNome(Nome.INGLES);
        listIdioma.get(2).setCurriculo(curriculo);
         
        curriculo.setIdioma(listIdioma);
        curriculo.setObjetivo("teste");         
        curriculo.setPessoa(p);
         
        session.merge(p);
         
        tx.commit();
        session.flush();
        session.close();
    }
Responder

Gostei + 0

27/08/2010

Dyego Carmo

Faz um teste por favor:

Antes de fechar a sessao coloque:


session.update(listIdioma.get(0));
session.update(listIdioma.get(1));
session.update(listIdioma.get(2));
Responder

Gostei + 0

30/08/2010

Fabiano Souza

fiz mais esse teste a não funciona.. apenas as tabelas pessoa e curriculo são alteradas.. nada acontece na tabela Idioma (onde estão os campos enums)....

eu criei uma app para testar esse problema se vc concordar posso te mandar por email.. se vc tiver o oracle instalado vai levar 5 min. pra instalar... tem os comandos para criar as 3 tabelas e a classe de teste... só vai precisar alterar o arquivo config do hibernate...
Responder

Gostei + 0

30/08/2010

Dyego Carmo

Mande por favor...

Responder

Gostei + 0

30/08/2010

Fabiano Souza

já mandei.. valeu
Responder

Gostei + 0

03/09/2010

Fabiano Souza

encontrou alguma coisa?
Responder

Gostei + 0

06/09/2010

Dyego Carmo

Opa !


Eu nao recebi , poderia tentar denovo ?

Mande tmb para dyego.leal@gmail.com !!!!

Responder

Gostei + 0

08/09/2010

Fabiano Souza

acabei de mandar..

Obrigado!
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar