Fórum problema ao persistir entidade com campo tipo enum #383829
17/08/2010
0
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
Curtir tópico
+ 0Posts
17/08/2010
Dyego Carmo
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(""))
Gostei + 0
18/08/2010
Fabiano Souza
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)
Gostei + 0
19/08/2010
Dyego Carmo
Já tentou realizar este mapeamento utilizando anotações ? é até mais facil !
Gostei + 0
23/08/2010
Fabiano Souza
<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)
Gostei + 0
25/08/2010
Dyego Carmo
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 !
Gostei + 0
26/08/2010
Fabiano Souza
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();
}
Gostei + 0
26/08/2010
Dyego Carmo
Crie um construtor nestes daos e passe o session que vc instancia por primeiro para eles utilizarem , teste e me fale.
Gostei + 0
27/08/2010
Fabiano Souza
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();
}
Gostei + 0
27/08/2010
Dyego Carmo
Antes de fechar a sessao coloque:
session.update(listIdioma.get(0));
session.update(listIdioma.get(1));
session.update(listIdioma.get(2));
Gostei + 0
30/08/2010
Fabiano Souza
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...
Gostei + 0
30/08/2010
Dyego Carmo
Gostei + 0
30/08/2010
Fabiano Souza
Gostei + 0
03/09/2010
Fabiano Souza
Gostei + 0
06/09/2010
Dyego Carmo
Eu nao recebi , poderia tentar denovo ?
Mande tmb para dyego.leal@gmail.com !!!!
Gostei + 0
08/09/2010
Fabiano Souza
Obrigado!
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)