Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Duvida JPA

Montei meu repositório de JPA mas eu tentar testar dá o seguinte erro:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at br.com.alura.escola.MatriculaAlunoJPA.main(MatriculaAlunoJPA.java:19)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: escola] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1597)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1503)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at br.com.alura.escola.infra.aluno.JPAUtil.<clinit>(JPAUtil.java:9)
    ... 1 more
Caused by: org.hibernate.MappingException: Could not determine type for: br.com.alura.escola.dominio.aluno.CPF, at table: Alunos, for columns: [org.hibernate.mapping.Column(cpf)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:515)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:482)
    at org.hibernate.mapping.Property.isValid(Property.java:231)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:627)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:267)
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:359)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:314)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
    ... 5 more

Nisso minha classe Aluno já está com a anotação @Entity, criei um Long id e um construtor vazio além do que já tinha:

package br.com.alura.escola.dominio.aluno;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "Alunos")
public class Aluno {

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private CPF cpf;
    private String nome;
    private Email email;
    private List<Telefone> telefones = new ArrayList<>();

    private String senha;


    public Aluno() {
    }

    public Aluno(CPF cpf, String nome, Email email) {
        this.cpf = cpf;
        this.nome = nome;
        this.email = email;
    }

    public void adicionarTelefone(String ddd, String numero) {
        this.telefones.add(new Telefone(ddd, numero));
    }

    public String getCpf() {
        return cpf.getNumero();
    }

    public String getNome() {
        return nome;
    }

    public String getEmail() {
        return email.getEndereco();
    }

    public List<Telefone> getTelefones() {
        return telefones;
    }

    public String getSenha() {
        return senha;
    }

}

A classe que criei para testar:

package br.com.alura.escola;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import br.com.alura.escola.dominio.aluno.Aluno;
import br.com.alura.escola.dominio.aluno.CPF;
import br.com.alura.escola.dominio.aluno.Email;
import br.com.alura.escola.infra.aluno.AlunosRepositoryComJPA;
import br.com.alura.escola.infra.aluno.JPAUtil;

public class MatriculaAlunoJPA extends AlunosRepositoryComJPA{

    public static void main(String[] args) {

        Aluno aluno = new Aluno(new CPF("123.123.123-44"), "Jones", new Email("jones@gmail.com"));
        aluno.adicionarTelefone("11","948471381"); 

        EntityManager em = JPAUtil.getEntityManager();

        em.getTransaction().begin();


        em.persist(aluno);
        em.getTransaction().commit();
        em.close();


    }

}

Tentei começar a mapear as classes de CPF, Email e Telefone mas sem sucesso. Inclusive até cheguei a transformar elas em entidades apesar de que não fazer muito sentido pro projeto pois elas deveriam ser só VOs e tentei anotações @OneToOne e etc, mas também não deu certo.

Quanto ao persistence.xml e ao resto está tudo certo, o problema está ao tentar criar a tabela no DB.

Acredito que posso estar tendo problemas com mapeamento.. como deveria ser feito pra que o teste de JPA rode sem problemas?

Com um norte creio que já consigo prosseguir .

3 respostas

Oi Matheus.

Tem umas sugestões bem interessantes nessa thread do StackOverflow, veja: Mapping Exception

Talvez o problema possa ser resolvido com algumas anotações.

solução!

Oi Matheus,

O problema está nos atributos cpf, telefones e email. Como eles não são classes do Java(String, Long, etc.) e nem entidades, a JPA não sabe como mapeá-los em colunas na tabela.

Nesse caso você pode utilizar o recurso de Embeddable da JPA para mapear o cpf e o email, e utilizar o @ElementCollection para mapear os telefones.

Bons estudos!

Segui as sugestões e consegui subir o projeto usando Embeddable e @ElementCollection, obrigado!