JPA Mini Livro – Primeiros passos e conceitos detalhados

Quais os motivos que levaram à criação do JPA

Um dos grandes problemas da Orientação a Objetos é como mapear seus objetos para refletir o banco de dados. É possível ter uma classe com o nome de Carro mas seus dados estarem salvos em uma tabela chamada TB_CARRO. O nome da tabela seria apenas o começo dos problemas, se sua classe Carro tem o campo “nome” mas na tabela está como STR_NAME_CAR?

O framework mais básico do Java para acessar o banco de dados é o JDBC. Infelizmente, com o JDBC, é necessário um trabalho braçal para transformar o resultado que vem do banco de dados em uma classe.

Para obter objetos do tipo carros (no código abaixo está como Car) vindo do banco de dados utilizando JDBC seria necessário ter o código abaixo:

import java.sql.*;
import java.util.LinkedList;
import java.util.List;

public class MainWithJDBC {
	public static void main(String[] args) throws Exception {
		Class.forName("org.hsqldb.jdbcDriver");

		Connection connection = // get a valid connection

		Statement statement = connection.createStatement();

		ResultSet rs = statement.executeQuery("SELECT "Id", "Name" FROM "Car"");

		List<Car> cars = new LinkedList<Car>();

		while(rs.next()){
			Car car = new Car();
			car.setId(rs.getInt("Id"));
			car.setName(rs.getString("Name"));
			cars.add(car);
		}

		for (Car car : cars) {
			System.out.println("Car id: " + car.getId() + " Car Name: " + car.getName());
		}

		connection.close();
	}
}

No código acima é possível ver como é trabalhoso transformar os valores retornados pela consulta em objetos. Imagine uma classe com 30 campos… Para piorar imagine uma classe com 30 campos e relacionado com outra classe que também tenha 30 campos? Por exemplo, um Carro pode ter uma Lista de Pessoas e cada objeto da classe Pessoa teria 30 campos.

Outra desvantagem de uma aplicação que utiliza o JDBC puro é a sua portabilidade. A sintaxe de cada query pode variar entre bancos de dados. Para se limitar o número de linhas de uma consulta na Oracle se utiliza a palavra ROWNUM, já no SQL Server é utilizado a palavra TOP.

A portabilidade de uma aplicação que utiliza JDBC fica comprometida quando as queries nativas de cada banco são utilizadas. Existem soluções para esse tipo de problema, por exemplo, é ter cada consulta utilizada salva em um arquivo .sql fora da aplicação. Para cada banco diferente que a aplicação rodasse um arquivo .sql diferente seria utilizado.

É possível encontrar outras dificuldades ao longo do caminho: como atualizar os relacionamentos de modo automático, não deixar registros “órfãos” na tabela ou como utilizar hierarquia de um modo mais simples.

196 thoughts on “JPA Mini Livro – Primeiros passos e conceitos detalhados

  1. Parabéns pelo post. Gostaria de verificar contigo se é realmente possível utilizar @PersistenceContext no tomcat7. Tentei realizar a injeção através do @PersistenceContext porém, minha instância do EntityManager é sempre nula.

    Obrigado

    • Olá André, bom dia.

      Com Tomcat a injeção não é possível.

      Eu até alterei o post para deixar isso mais claro.

      Obrigado pela visita.

        • Marco, boa tarde.

          No ambiente JEE para os “objetos injetados” é aconselhável utilizar um método anotado com @PostConstruct. [=

          Agora eu não tenho a mínima idéia do que você quiser dizer com “eu faço isso…”, isso o que rapaz? MAhahua

          Obrigado pela visita.

    • Carutcho, boa tarde!!!

      Rapaz, do que seria o mundo? O mesmo que será quando o uaiPartyBoy vier ao mundo!

      Até lá o teu blog seja criado, eu vou tocando o meu aqui! [=

      Obrigado mesmo pelo apoio. [=

  2. Parabéns pelo post.

    Gostaria de saber como faço para consultar e retornar o valor do ‘descriminator’ para minha entidade?

  3. Estou usando o Play! Framework 2.0 e estou percebendo alguns comportamentos estranhos. No caso da Herança (@Inheritance(strategy = InheritanceType.JOINED)) mesmo que eu mude o tipo para TABLE_PER_CLASS, ele continua colocando todos os dados na mesma tabela. O que não é um problema de fato pra mim, mas não deixa de ser estranho.

    Agora o que me parece ser um problema é nesse caso da SecondaryTable, pois eu fiz desta forma que você escreveu e não é criado nenhum tipo de link entre elas. A minha linha de código está assim:

    @SecondaryTables({
    @SecondaryTable(name=”conta”, pkJoinColumns={@PrimaryKeyJoinColumn(name=”associado_id”)}),
    @SecondaryTable(name=”endereco”, pkJoinColumns={@PrimaryKeyJoinColumn(name=”associado_id”)})
    })

    E o campo associado_id não é criado nas tabelas conta e endereço. Eu deveria criar este campo manualmente? Eu entendo que esta seria uma forma alternativa para o OneToOne, certo? Ainda não achei nada na documentação que confirme este comportamento, mas sei que o OneToOne funciona, apenas queria usar desta outra forma por achar mais elegante.

    E no mais, parabéns pelo EXCELENTE mini-livro. Está salvando o desenvolvimento da nossa equipe.

    Abraços
    -Alvaro C.
    ———————————————
    Bom, parece que não tem suporte mesmo. Ao menos é o que (não a)parece nessa cheat sheet:

    http://playcheatsheet.appspot.com/show/ArtemMedeu/armed/play-cheatsheets

    • Alvaro, boa tarde.

      Editei suas mensagens e as coloquei em uma mensagem apenas.

      Realmente parece não dar suporte, mas não tenho como te dar suporte neste framework.

      Obrigado pela visita e pelo apoio.

      • Me desculpe Hébert… poxa vida, sinto muito mesmo… É que eu estava estudando dois materiais quase que ao mesmo tempo, ai confundi o nome, mas o elogio foi pra ti mesmo… Mais uma vez me desculpe pela gafe e reforço os parabéns pelo material.

    • Willian, boa tarde.

      Prometo para você de pé junto que elogio e apoio nunca é demais! =D

      Fico feliz por saber que eu ajudei! o_

  4. Ja que prometeu que elogio e apoio nunca é de mais…
    Então vou elogiar :) kkkkkk vc merece cara, tanto pelo teu blog, quanto pelo teu apoio no guj.. admiro mesmo jakefrog lol kkkk

    só que… depois quero fazer uma perguntinha que nao vi no post.. vou dar uma lida com calmaa e direitnnho pra ver se não foi engano meu.. Mas se nao achar vou psotar beleza?

    Abraço!

    • Opa, valeu mesmo pelo apoio! o/

      Pode perguntar sim, se eu não conseguir ajudar a gente leva a dúvida pro GUJ que alguém ajuda. [=

      Obrigado pela visita e pelo apoio. [=

  5. Parabéns pelo post, e principalmente parabéns para o blog.

    o seu conteúdo é muito bom, você precisa investir em SEO amigo, começando por URL amigáveis.

    que com esse conteúdo, logo logo estará no top do google.

    abraços

    • Eduardo, boa tarde.

      Muito obrigado pela força.

      Eu cheguei a olhar a questão da URL mais amigável, o problema era que eu teria posts de nome repetidos. Tudo aqui vai em PT/EN se fosse para alterar hoje, aconteceria esse problema e teria problemas quanto aos links que hoje já apontam para meu blog. =/

      Vou olhar se existe alguma soluçao para meu caso, obrigado pela dica.

      Hoje eu já apareço em primeiro no google em diversos tipos de pesquisas, mas não custa nada melhorar mais né?! ;)

  6. Cara parabens. É muito dificil achar um material com qualidade na internet. Material se acha aos montes porem “material com qualidade” anda cada vez mais escasso.

    A objetividade e a simplicidade com o qual aborda os conceitos é muito bacana, isso ajuda muito quem está começando.

    Espero que continue postando materiais desse nivel.

    abraço

    • Anderson, boa noite.

      Fico feliz por saber que você gostou do material.

      Espero que você possa voltar mais vezes.

      Obrigado pelo apoio! =D

  7. É Jake, infelizmente estou apanhando aqui, mas é com consultas. Bom, não sei se posso abusar de vc, mas o que eu estou tentando fazer é uma busca dinâmica… Mas tudo o que consegui fazer até agora é:

    // filters
    List predicates = new ArrayList();

    for (Entry entry : filters.entrySet()) {
    //Selecione… não é um filtro válido :)
    if(entry.getValue().equals(noneSelected)){
    continue;
    }[//só pego e trato como String :( isso ta mto ruim
    Expression literal = criteriaBuilder.literal( “%”+entry.getValue()+”%”);
    predicates.add(criteriaBuilder.like(from. get(entry.getKey()), literal));
    }
    accountQuery.where(predicates.toArray(new Predicate[predicates.size()]));

    • Marco, boa noite.

      Infelizmente não tenho como te ajudar sem analisar tudo o que você tem e onde você quer chegar.

      O povo do GUJ pode te ajudar com certeza! =D

      Inté!

  8. Cara, vou estudar JPA pelo seu material, gostei demais… abraço…se você ainda nao gerou o PDF, eu vou tentar compilar essa coletânea de posts em um arquivo pdf.

    Obrigado por perder tempo explicando as coisas para nós leigos.

    • João, boa noite.

      Muito obrigado pelo apoio, fico feliz em saber que pude ajudar.

      Quanto ao PDF, agradeço muito se você o fizer. [=

    • Albert, bom dia.

      Agradeço o apoio e a idéia.

      Já venho pensando nisso, e atualmente estou finalizando um livro sobre JSF.

      Quem sabe o de JPA não aparece no pedaço né!? [=

      Obrigado pela visita.

      Me perdoe a demora em responder, realmente estou muito ocupado nesses dias. =/

  9. Estou com uma dificuldade, criei uma herança TABLE PER CLASS com @Id
    @GeneratedValue(strategy = GenerationType.AUTO), porém quando vou fazer o deploy ele da o seguinte erro:
    org.hibernate.MappingException: Cannot use identity column key generation with mapping for: …

      • Classe abstrata:
        @Entity
        @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
        public abstract class AbstractEmpresa implements Serializable, PessoaJuridica {

        @Id
        @GeneratedValue(strategy = GenerationType.TABLE)
        @Column(name = “INDICE”)
        protected Long id;

        classe que extende:
        @Entity
        @Table(name = “EMPRESA”)
        public class EmpresaPrestadora extends AbstractEmpresa implements Serializable {

        só que ele da aquele erro, e outra li em alguns foruns que o TABLE_PER_CLASS não suporta o identity, estou tentando utilizar o TABLE, porém estou com algumas dificuldades, pois ele não persiste e nao dá erro algum

        • Guilherme, bom dia.

          Infelizmente não tenho uma idéia de qual problema estaria acontecendo sem analisar melhor seu código.

          Poste seu código no GUJ para outras pessoas (se não eu) poderem te ajudar melhor. Lá o código fica melhor formatado.

          Obrigado pela visita.

  10. Muito bom seus post

    Mas tenho uma duvida no relacionamento OneToMany e ManyToOne bidirecional, estou tentando realizar um cadastro, o qual o lado OneToMany (entidade Aquisicoes) possui uma lista da entidade Aquisicoes_Ir, e na entidade Aquisicoes_IR eu tenho uma variavel do tipo Aquisicoes a qual recebera a chave estrangeira, segundo seu post o lado Many que manda no relacionamento. Meu cadastro é realizado mas a chave estrangeira não é salva, fica null.

    O que eu preciso fazer para gravar tbm a chave estrangeira? no relacionamento OneToMany(mappedBy=”aquisicao”, cascade= CascadeType.ALL)utilizo para quando eu gravar os dados em Aquisicao a entidade Aquisicao_Ir tbm grave os valores da lista.

    • Luciano, boa tarde.

      Olhando pelo que você descreveu não consigo resolver seu problema.

      Talvez o pessoal do GUJ possa te ajudar.

      Até mais.

  11. Cara Parabéns pelos seus ótimos post’s.
    Sempre indico aos meus amigos e sempre acompanho o seu trabalho. Muito bom e já me tirou dezenas de dúvidas.

    Abraço.

  12. No final deste artigo voce fala que “Não existe auto relacionamento”.

    E coloca que tem que fazer

    person.setCellular(cellular);
    cellular.setPerson(person);

    A pergunta é, onde eu devo colocar este codigo??

    • Eliseu, bom dia.

      Esse código deve ser feito antes do objeto ser salvo.

      Exatamente antes do persist. [=

      Espero ter ajudado, obrigado pela visita.

    • David, bom dia.

      Se você for reparar, qualquer modo de utilizar o DB hoje amarra a aplicação.

      Por exemplo, ao mapear uma coluna se poderia fazer @Column(name=”idade_pessoa”). Ao fazer a consulta por JDBC você teria que fazer select idade_pessoa o que acabaria refletindo do mesmo modo. Se houver uma alteração no nome da coluna de idade_pessoa para idade, tanto um código JDBC como JPA necessitaria de ser alterado. [=

      Espero ter esclarecido.

      Obrigado pela visita.

    • Crazy, boa tarde.

      Obrigado pelo apoio. [=

      Estou pensando em escrever um sobre EJB e um Maven com mão na massa, diversos projetos prontos por página.

      Estou com um pronto de Spring para lançar daqui uns dias sobre paginação, depois disso, volto para os minilivros. [=

      Não comecei ainda pois estou escrevendo um livro real! :D

  13. Ola Hebert:

    Parabens pelo mini livro, gostei.

    Consegui rodar o exemplo mas no campo dog_class_name da tabela Dog sempre fica NULL.

    mysql> select * from DOG;
    +—-+—————-+——+
    | id | dog_class_name | name |
    +—-+—————-+——+
    | 1 | NULL | uno |
    | 2 | NULL | dos |
    +—-+—————-+——+
    2 rows in set (0.00 sec)

    mysql> select * from DOG1;
    +—-+—————+
    | id | hugepooweight |
    +—-+—————+
    | 1 | 1 |
    +—-+—————+
    1 row in set (0.00 sec)

    mysql> select * from DOG2;
    +—-+————+
    | id | littlebark |
    +—-+————+
    | 2 | dos2 |
    +—-+————+
    1 row in set (0.00 sec)

    • Tany, bom dia.

      Creio que há algo muito errado com seu código. Afinal, por que tabela para DOG1 e DOG2?

      Obrigado pela visita e desculpe a demora em responder.

  14. Ola Hebert:

    1) Estou tentando rodar o exemplo do page 15 (Mapeando Heranças – Table Per Concrete Class), mas nao estou conseguindo.
    O eclipse da o warning “uses table-per-concrete-class inheritance which is not portable and may not be supported by the JPA provider”. Eh por isso que nao estou conseguindo rodar?.
    Eu estou utilizando hibernate (JPA2)

    2) Eh so’ 2 tabelas mesmo? (ou esta faltando uma (tabela Dog)?)

  15. Boa noite Hebert, gostaria de uma resposta franca sua.
    1° Jpa ajuda bastante na parte de persistência, sem contar que a aplicação não fica presa a um único banco de dados, porem uma aplicação que é desenvolvida sem a utilização do JPA tem um maior desempenho?
    2° Se de fato ouver essa perca desempenho em um projeto web valeria apena utilizar o mesmo?

    Fico muito em duvida, ainda mais depois de absorver os conteúdos postados aqui.

    Parabéns pela qualidade de seus post’s e obrigado por compartilhar o seu vasto conhecimento!

    • Joel, boa noite.

      Essa pergunta feita frequentemente em nossa área, e as vezes mal respondida ou executada.

      Um livro que eu li disse que em diferentes casos a vantagem pode ser do JPA ou do JDBC, mas em geral, dê preferência ao JPA.

      Se mal utilizado o JPA poderá destruir a performance da aplicação, assim como um JDBC também poderia.

      É normal dizer que o JDBC é melhor que o JPA para aplicação que têm milhares de transações por minuto ou minutos. É uma camada a menos para a persistência.

      JPA tem vantagens como melhorar o tempo de desenvolvimento, elimina a necessidade de sempre escrever scripts SQL, melhora a portabilidade da aplicação, utiliza de cache de dados e assim vai. [=

      Se JDBC não for requisito vá de JPA. =D

      Obrigado pela visita e pela confiança.

  16. Olá Hebert,

    usando JPA c/ herança desta forma (TABLE_PER_CLASS), como ficaria o atributo da classe “HugeDog” responsável pelo relacionamento entre as tabelas Dog e HugeDog no SGBD?

    Por exemplo:

    class HugeDog extends Dog {
    @Column(name = “ID_DOG”)
    @OneToOne
    private Dog dog;
    }

    • Leonardo, boa tarde.

      Não entendi por que a classe estende DOG e ainda tem um objeto da mesma.

      Obrigado pela visita.

  17. Olá,

    Tenho uma dúvida sobre o mapeamento Join no seguinte cenário. Pessoa e Funcionário.

    Ao utilizar Join, o iden de Funcionário será o mesmo iden de Pessoa. Mas tenho a seguinte regra: Toda vez que o funcionário possui um novo cadastro na empresa (vamos imaginar que ele entrou na empresa, saiu e voltou) , teria então dois registros do funcionário, mas somente um registro de Pessoa.

    Como ficaria isso, tenho uma única pessoa vinculada a duas filhas? Gostaria de utilizar a estrutura da herança, mas sem a necessidade de ter uma relação 1 para 1 com a classe superior. (E manter a normalização)

    • Halley, boa tarde.

      Nesse caso não se tem herança, e sim uma agregação. E não seria 1 para 1, mas 1 para muitos pois uma pessoa pode ter mais de um funcionário.

      Obrigado pela visita.

  18. Hebert, estou usando JPA com swing, como faço pra excluir um registro na tabela resultante da junção entre duas tabelas many-to-many? Tipo: Tenho a tabela Car e a tabela Person com relacionamento muitos-pra-muitos, isso criaria uma terceira tabela, o que quero e remover o registro nesta terceira mantendo os dados das outras duas como posso fazer isso usando as classes de entidades geradas pelo Netbeans?

  19. Testei com o Hibernate nativo do Netbeans e com o 4.1.7 com o driver postresql mas as PK’s da tabela adicional não são geradas. Já passou por isso ? Criei na mão. Tem um exemplo de pesquisa usando essas tabelas ? Obrigado

    ———————

    Criou os PK usando ManyToMany com campos adicionais :/

    • Eduardo, boa noite.

      Para te ajudar eu precisar ver o código e infelizmente aqui o código fica horrível.

      Post no GUJ sua dúvida que lá, se não eu, outra pessoa te ajudará.

      Obrigado.

  20. Hebert, pra fazer a associação bidirecional, eu preciso fazer o mappedBy no @OneToMany e no
    @ManyToOne tenho que colocar @JoinColumn(name = “cellular_id”)? Ou só preciso declarar em uma?

    • erick, bidirecional quer dizer relacionamento dos dois lados.

      Leia sobre todos os relacionamentos que isso é explicado. Comece a partir do one to one.

      Até mais.

  21. Ola Hebert estou com um problema em recuperar a super classe, sem ser por chave por um atributo qualquer. o Hibernate faz um join tem como forçar o hibernate a nao fazer os joins ?

    • Josias, boa noite.

      Se sua classe tiver com algum EAGER ou relacionamento terminado em One, ele fará o Join.

      A solução é deixar o relacionamento como LAZY.

  22. Olá Hebert:

    Parabens pelo trabalho.

    Estou fazendo um projeto seguindo orientações desse post, porém não conseguir encontrar um exemplo de um mapeamento manyToMany onde um dos objetos tem compositeID, vc poderia mostrar um exemplo?

  23. Muito bom o conteúdo! Não só nesse post, mas em todos os outros que li até agora.
    Há muitos exemplos bons na própria documentação do Hibernate, porém, lá é meio confuso por ter muita informação em pouco espaço. Você conseguiu separar tudo direitinho, de forma bem didática. Melhor passo-a-passo sobre JPA / Hibernate que li até agora (e olha que estou pesquisando já faz uma semana). Parabéns!

    • Olá Marcelo, boa tarde.

      Aqui no blog mesmo já tem esse exemplo, procure pela tag de business que você encontra.

      Obrigado pela visita.

  24. Boa tarde! Parabéns pelo seu blog e pelo seu livro! Estou começando no mundo java e eles tem me ajudado a aprender cada vez mais!
    Mas preciso de uma ajuda sua! A minha duvida é a seguinte: o sistema tem uma tabela de logins onde o login pode ser de um funcionário ou de um cliente, fazendo com que a tabela contenha uma chave estrangeira (que aceita null) para cada umas destas outras tabelas (funcionário e cliente). A intenção de ter a tabela de login separada foi para evitar que houvesse duplicidade de login. A estrutura é mais ou menos a seguinte (os outros campos foram omitidos para simplificar):

    Tabela Funcionario: codigo (int), nome (varchar)
    Tabela Cliente: codigo(int), nome(varchar)
    Tabela Login: chave(varchar), senha(varchar), codigoFuncionario(int – null – fk), codigoCliente(int – null – fk).

    Como deveria ficar o mapeamento destas entidades utilizando o @oneToOne.

    Obrigado,
    Leonardo

    • Leonardo, boa tarde.

      Basta utilizar a anotação @JoinColumn para definir a chave dentro da Entity.

      Obrigado pela visita.

  25. Olá Hebert, primeiro parabéns pelo post.

    No caso de um Sistema de Biblioteca, onde existem as entidades Livro e Autor pode se aplicar o relacionamento @ManyToMany no dois lados?

    Visto que um livro tem geralmente mais do que um autor, e cada autor pode ter mais de um livro.

  26. Hebert,

    Na página 22 você comenta sobre “ManyToMany com campos adicionais” e na tabela que possui o ID entre o relacionamento, no caso PersonDogId, sobrescreve o HashCode e como retorno faz a soma das variáveis int que representam os id’s da tabela Person e Dog (return person + dog;).
    Tenho uma necessidade parecida, porém meus id’s não são do tipo int e sim do tipo Long, desta forma não é possível que eu sobrescreva o HashCode da mesma maneira, uma vez que o retorno do mesmo é um int e não um Long.
    Minha pergunta é: é realmente necessário sobrescrever o HashCode desta forma? E se sim, existe alguma solução para o meu caso? Ou a única solução é trocar meus id’s para Integer?

    • Flávio, boa tarde.

      Você deve sobrescrever, mas você pode fazer um CAST de Long para int que funcionará do mesmo modo.

      Inclusive Long já tem um método onde você pode extrair um valor int.

      Obrigado pela visita.

  27. Olá Hebert. Ótimo post!

    Caso eu queira persistir a classe PersonDog, recuperando um Person do banco, ocorre o erro: “detached entity passed to persist: Person”

    O código:


    PersonDog personDog = new PersonDog();

    //Recupero person do banco
    Person person = personDAO.find(1);

    //seto person para Person dog
    personDog.setPerson(person);

    Dog dog = new Dog();
    dog.setName(“Totó”);

    person.setDog(dog);

    //Aqui ocorre o erro
    personDogDAO.persist(personDog);

    Tem alguma ideia do que pode estar ocorrendo?

    Se eu CRIAR um Dog e Person, persiste normalmente. O erro ocorre quando eu recupero um person ou um dog do banco e tento persistir PersonDog

    • Bruno, boa tarde.

      Esse erro acontece pois DOG está detached.

      Por isso que no post os dois foram persistidos separadamente.

      Dê uma olhada no post aqui no blog: Mini Livro JPA.

      Ele explica melhor esse erro.

      Obrigado pela visita.

  28. Olá Hebert!

    Sobre o tópico “Criando um EntityManagerFactory por aplicação” se fosse como o código abaixo, em um genericDao, o JPA faria a analise de todo o banco e demais informações sempre q instanciasse um novo dao ?

    private static EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(“MyPersistenceUnit”);

  29. Olá Hebert,

    Muito bom o tutorial. Estou estudando JPA e JSF e tenho uma dúvida, acredito que cabe neste contexto.
    Já vi muito na internet em projetos que tomei como exemplo que normalmente cria-se uma classe JPAUtil para inicializar o EntityManagerFactory e EntityManager, estou correto??
    Mas a questão é, em que pacote posso deixar essa classe?? Talvez isso seja uma questão de Design Pattern… não sei, me corrija se estiver errado por gentileza.
    Posso ter um pacote utilidade e o mvc normal com um DAO??
    Espero que tenha entendido….
    Obrigado!!

    • Joabe, bom dia.

      Bem o JPAUtil não é um Pattern ou coisa do tipo, pelo menos nunca vi algo. Poderia servir para qualquer coisa, mas vamos focar no caso de apensa controlar EntityManager e EntityManagerFactory.

      Eu te aconselharia a deixá-lo perto de quem o utilizará, e se for o caso, até mesmo com nível de pacote.

      Se apenas o DAO teria acesso ao DB, apenas ele teria que ter acesso a essa classe.

      Se um Facade da vida controlasse a transação, essa classe teria que ficar junto aos Facades.

      Espero ter ajudado, obrigado pela visita.

  30. Parabéns!! não só pelo o JPA Mini Livro, mas por todo conteudo que você disponibiliza aqui em seu site, digas muito boas e que tem me ajudado muito, e acredito também que tem ajudado muitos outros estudiosos do Java. E sera que teremos aqui um dia um EBJ MIni Livro? rsss..

  31. Hebert, boa tarde.

    Passando só para agradecer toda ajuda que seu blog tem me dado,
    e claro parabenizá-lo, além de um conteúdo bem elaborado,
    tem a atitude de compartilhar seu conhecimento!

    Fica na PAZ!

  32. Bom dia Hebert, meus parabens primeiramente pelo post, esta ajudando muito a todos, bom estou tendo um problema que se encaixa perfeitamente no seu tutorial, seu tutorial agregrou muito no meu conhecimento mais ainda não consegui resolver o meu problema, não sei se estou pecando em algum detalhe, para evitar uma publicação enorme, ja tenho a duvida postada na GUJ com os detalhes do que ocorre, segue o link

    http://www.guj.com.br/6205-jsf-problema-ao-salvar-listclientedependente-onetomany-com-hibernate

    Muito obrigado, até +

    • Erick, boa tarde.

      Eu vi que o pessoal respondeu lá.

      Obrigado pelo apoio e pela visita.

      Desculpe a demora em responder. Estou muito ocupado nesses últimos dias.

  33. Valew herbet era o que eu precisava muito bom, obrigado. Mas tenho uma dúvida, fiz deste jeito que vc postou aí criou corretamente tudo, mas na hora que eu vou dar o save no hibernate, ele não salva o objeto completo. Exemplo: no meu caso eu tenho Contrato, Cliente e ContratoCliente, quando eu salvo o contrato blz normal, mas a relação do cliente não é salva no ContratoCliente…(a coleção usada no OneToMany) você saberia o porquê?

    • Leonardo, boa tarde.

      Existem vários motivos. Você fez o relacionamento dos dois lados? a.setB(b) e depois b.set(a)? Seu relacionamento tem um dos lados marcado com mappedBY?

      Infelizmente, esse problema pode ser ocasionado por ambos motivos, mas os temas abordados aqui no post ensinam o modo correto de se salvar.

      Desculpe a demora em responder. Estou muito ocupado nesses últimos dias.

  34. Olá Hebert, quando eu uso o jpa e hibernate, e acontece um estouro de chave primaria ou estrangeira, como eu posso tratar a exceção, ela aparece no meu console, porém não consigo recuperar a exceção para tratá-la.

    • Rafael, boa tarde.

      Você terá que capturar essa exception e retentar a ação.

      Infelizmente não tem outro modo.

      Desculpe a demora em responder. Estou muito ocupado nesses últimos dias.

  35. Bom tarde,
    E qual seria o procedimento a ser tomado quando faz parte da chave composta tanto um atributo java e um objeto?
    Eu tenho uma tabela Endereço que tem como chave composta o idEndereco junto com idEmpresaFilial(fk para a tabela EmpresaFilial), relacionamento 1/1.

    • Michael, nesse caso você deve criar um objeto que faça esse relacionamento. Nele haverá o atributo int e a classe.

      Desculpe a demora em responder. Estou muito ocupado nesses últimos dias.

    • Marcello, boa tarde.

      Nesse caso você precisaria adicionar o CarId em outra classe.

      Não sei c entendi sua dúvida direito.

      Qualquer coisa poste suas dúvidas no GUJ, pois fica mais fácil de analisar código.

      Att,

  36. Prezado, Boa Noite.
    Muito interessante seu Mini Livro.
    Utilizo JPA, o ID como Identity e banco SQl Server 2008 R2. Após o persistir o dado necessito saber qual número foi atribuido ao ID e não sei como fazer.

    Vi que fala sobre o commit, mas não uso esta instrução, pois o DAo trata tudo automaticamente.

    Por favor, pode me ajudar?

    Obrigada

    • Cristina, boa tarde.

      Nesse caso, basta fazer getId() que o seu objeto já terá o ID gerado após o commit. Você não precisa ir ao banco buscar esse valor.

      Obrigado pela visita.

  37. Só confirmando, após colocar o parâmetro mappedBy em celular ele passou a ser a entidade mais forte do relacionamento, e pessoa continuou sendo a dona do relacionamento?

    Att,

      • Então no caso a entidade mais forte no trecho seguinte é cellular? ou pessoa seria a entidade mais forte?

        @OneToOne(mappedBy=”cellular”)
        private Person person;

        Att,

        • Ewerton,

          Quem ficará com a chave estrangeira? A tabela de pessoa ou a de celular?

          Leia o post novamente. Está descrito lá.

          Obrigado pela visita.

  38. Boa tarde,

    Se eu tenho o seguinte relacionamento: Empresa 1-1 Login | Usuario 1-1 Login
    Em Empresa e Usuario eu tenho o @OneToOne fazendo Join com loginId

    Ao fazer login, eu preciso saber se existe o mesmo na Empresa ou no Usuario, pra isso eu crio um findByLoginId em ambas entidades e ao fazer login eu vejo se existe o loginId. Isso é correto?
    No cadastro de usuário, ao se cadastrar eu preciso criar um novo Usuario e também um novo login para esse Usuario.

    A forma correta é dessa forma que eu fiz ou seria criar um relacionamento OneToOne bidirecional?

    • Marlon, boa tarde.

      Eu faria diferente, eu faria

      Empresa 1-N Usuário

      usuário/login seriam atributos de usuário. Outra coisa, é errado falar que Empresa e Usuário seria 1-1.
      A consulta seria algo como: select u from Usuario u where u.login = :login . Note que você poderia adicionar a empresa como Join na consulta.

      Qualquer coisa que precise de mais análise, poste no guj que o pessoal te ajuda lá postando códigos, aqui não é bom para postar código (fica tudo estragado).

  39. Hebert, já li seu MiniLivro de JPA inteiro, entendi bastante coisa, mais nesse sua explicação faltou um exemplo, não consigo de jeito nenhum imaginar com persistir os dados em N:M com campos adicionais. tem como vc fazer uma nova postagem ou implementar essa, ou então dar uma breve exemplo aqui?

    Agradeço desde já!

    • Ewerton, boa tarde.

      Infelizmente não exite suporte para código aqui nas respostas.

      O código postado nessa parte é funcional. Ele mostra como deve ficar o relacionamento, a parte de JPA, é a mesma já apresentada no post.

      A classe PersonDog tem o relacionamento, basta ela ser corretamente populada antes de ser persistida.

      Obrigado pela visita.

  40. Boa noite,

    Estou com problemas no relacionamento ManyToMany.
    Já li suas dicas e também referente ao post do erro “Lazy Initialization Exception”, porém não estava conseguindo parar o erro de Lazy.
    O porque do meu problema é que um Local N – N Categoria, ao fazer o fetch EAGER em Local, ele da o erro. Coloquei o FetchType.EAGER também em Categoria. Isso funciona, porém mesmo tendo 1 linha no banco, ele da um loop no resultado e fica repetindo o mesmo e nunca para. Você sabe o porque?

    • Marlon, boa noite.

      Infelizmente não sei te falar. Teria que analisar seu código, mas aqui não é um bom lugar para isso.

      Poste sua dúvida no GUJ que alguém (ou até mesmo eu) te ajudará.

      Obrigado pela visita.

  41. Hebert,

    No relacionamento ManyToMany Unidirecional, ou seja, eu vou acessar as informações apenas de 1 lado.
    Se eu já tiver as info no banco setadas manualmente eu consigo acessar as informações ou para ficar corretamente eu tenho que inserir as informações via aplicação com: “person.setDog(dogs);” | “dog.setPersons(persons);” e depois acessar elas?

    Att.

      • Hebert,

        Então no unidirecional eu uso apenas “a.setB(b)”?
        Se eu inserir as informações no banco manualmente funciona, ou só vou conseguir acessar informações que passaram por esse processo de relacionamento via código?

        Att.

        • Marlon,

          Você tentou? O que aconteceu? Faça o teste, insira a informação manualmente e depois pelo JPA e veja o resultado.

          O JPA nada mais é do que o banco de dados em forma de objetos. No caso de um relacionamento ele não precisaria de informação a mais.

          Att,

  42. se eu tenho uma classe Pesquisa e outra chamada MotivoPesquisa, levando em consideração que uma pesquisa só deve ter um motivo, mais um motivo pode ter 1 ou varios clientes. Como ficaria o relacionamento? OneToOne e OneToMany?

    • Alexandre, boa tarde.

      Não é o JPA quem define isso, é seu modelo.

      Se vai haver uma lista algum lado vai ser MANY.

      Obrigado pela visita.

  43. Hebert, bom dia

    segui o seu post “Utilizando Chave Composta Complexa”, porém recebo o
    seguinte erro:

    javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session

    Obrigada

    • Gabriela, boa tarde.

      Esse erro é por que existe uma transação aberta com a mesma entidade.

      Verifique se a conexão está sendo fechada ao final de cada chamada ao DB.

      Obrigado pela visita.

  44. Boa Tarde Herbert!

    Muito o bom esse seu post! venho usando esse seus posts mini livro como referencia em meus trabalhos! Obrigado!

    Tenho uma dúvida, ao mapear meu relacionamento descrito dessa forma, funcionou correntamente no banco de dados, porém, como posso utilizar esses objetos no cotidiano? primeiro tenho que instanciar um objeto tipo PersonDogId? tem algum exemplo de uso? obrigado novamente!

    • Bruno, boa tarde.

      Exato, se você já tem os dados da chave que está procurando você deve instanciá-lo e utilizá-lo na hora da consulta.

      Obrigado pela visita e pelo apoio.

  45. Hebert, no mapeamento ManyToMany temos uma lista da outra classe e não o objeto, já que há uma tabela intermediária entre elas, então como fazer o set do objeto da outra?
    person.setDog(dogs);
    dog.setPersons(persons);

    e onde fazemos essas chamadas?

    • Alexsandro, boa tarde.

      Não entendi qual o seu problema.

      Obrigado pela visita, e desculpe a demora em responder. Estive muito ocupado nesse último mes.

  46. Hebert,

    Tenho um caso parecido com este porém as minhas chaves são do tipo Long.
    E quando eu tento persistir no banco eu recebo a exceção abaixo:

    javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.lang.Long.

    Saberia me ajudar?

    • Cleber, boa tarde.

      Nunca vi esse erro antes, e isso pode variar do seu banco ou até mesmo do seu driver JDBC.

      Obrigado pela visita, e desculpe a demora em responder. Estive muito ocupado nesse último mes.

  47. Olá,
    Primeiramente gostaria de parabenizá-lo pelo post. Gostaria de saber se teria como baixar o código fonte dessas classes. A minha dúvida é como abordaria dentro da classe as linhas call.setCellular(cellular); e
    cellular.setCalls(calls);
    Obrigada,
    Evellyn

    • Evellyn, boa tarde.

      Todo o código fonte já foi descrito nas páginas.

      Obrigado pela visita, e desculpe a demora em responder. Estive muito ocupado nesse último mes.

  48. Boa Tarde Herbert!

    Venho usando seus posts para resolver muitos problemas com mapeamento.

    Mas esse ManyToMany com adicionais não estou conseguindo resolver, continuo trabalhando com o HistoricoSituacaOportunidade ou mudo para HistoricoSituacaOportunidadeId?

    Você tem algum link para um uso direto desse relacionamento?

    Agradeço desde já!

    • Adriano, boa tarde.

      O material que tenho está na página de mapeamento avançado com @ManyToMany.

      Obrigado pela visita, e desculpe a demora em responder. Estive muito ocupado nesse último mes.

  49. Olá Hebert,

    Muito bom seus post aprendi bastante com eles inclusive com seu livro JPA Eficaz, muito bom mas como sempre temos alguns pequenos problemas durante o percurso, eu estou tentando atualizar somente a entidade endereço de pessoa usei o mapeamento @OneToOne, consigo inserir, deletar endereço e pessoa e atualizar somente a pessoa, gostaria de saber de você como faço para alterar somente o endereço, tentei fazer como você fez no seu projeto de pessoa e cachorro onde tinha um para buscar os dados do cachorro e atualiza-lo, mas também sem sucesso, to utilizando JPA, JSF, Hibernate e Tomcat7.

    Desde já muito obrigado pela atenção.

    Atenciosamente,
    Heberson Rocha Aguiar

    • Heberson, boa noite.

      Honestamente não sei te falar pois não sei o que seu código está fazendo.

      Infelizmente não tenho como analisar código aqui pois o código quebra. Poste sua dúvida no GUJ/Stack Overflow (http://pt.stackoverflow.com/) que alguém, ou até mesmo eu, vou ajudar.

      Att,

  50. Hebert,
    necessitei fazer este mesmo mapeamento da lista de ENUM, porem o resultado que obtive foi outro. Ao persistir a entidade obtive o seguinte erro:

    ibernate: insert into classified (ind_classified_type, dat_creation, dat_update, des_contact, des_description, des_title, idt_user_creation) values (?, ?, ?, ?, ?, ?, ?)
    Hibernate: insert into classified_classifiedCategories (classified_idt_classified, element) values (?, ?)
    2014-04-17 08:41:17,575 WARN [org.hibernate.util.JDBCExceptionReporter] SQL Error: 1146, SQLState: 42S02
    2014-04-17 08:41:17,575 ERROR [org.hibernate.util.JDBCExceptionReporter] Table ‘classified_classifiedCategories’ doesn’t exist
    repare que o Hibernate gera dois inserts…

    De fato não existe nenhuma tabela classified_classifiedCategories , fui atras deste mapeamento justamente para ter o beneficio de não ter que criar uma tabela para o ENUM.

    Poderia me ajudar ou me esclarecer ?

    • Flávio, bom dia.

      Se você tem uma listagem de ENUM será necessário ter outra tabela.

      Se você tiver apenas um ENUM basta anotar com @Enumerated.

      Obrigado pela visita

  51. Uaihebert, olá…
    Cara, voce comenta, na parte Chave simples composta @IdClass que é possivel utilizar @GeneretedValue no atributo serial. Corrija-me se eu estiver errados, mas… Os bancos de dados não seriam projetados para você fornecer suas próprias chaves primárias compostas de valores não-gerados automaticamente???
    Tentei utilizar o @GeneretedValue e meu mysql se perde tentando transformar o atributo brand em auto_increment… :P

    —-

    “…fornecer suas próprias chaves primárias compostas de valores não-gerados automaticamente…”.
    Considere isto somente neste caso… :)

    ——-

    Achei outro problema. Utilizando @InheritanceType.TABLE_PER_CLASS, não consigo utilizar a anotação @GeneratedValue(strategy=GenerationType.AUTO) no ID da superclasse.
    Só funciona quando eu retiro esta anotação. Alguma ajuda? :)

    • Douglas, bom dia.

      Desculpe a demora em responder suas perguntas, estou trabalhando no mínimo 10h por dia e estou sem tempo para tomar conta do blog. =(

      Veja, eu fiz rapidamente um exemplo de como gerar um ID automaticamente com Chave Composta:
      @Entity
      @Table(name = “MY_TABLE”)
      @IdClass(DummyEntityKey.class)
      public class DummyEntity {
      @Id
      @GeneratedValue
      private int valor;

      @Id
      private String outroValor;
      // get/set
      }

      Isso aí já funciona. Classe DummyEntityKey só tem os mesmo atributos com o mesmo nome. Para gerar a chave automática a única coisa que eu fiz foi:

      final DummyEntity dummyEntity = new DummyEntity();
      dummyEntity.setOutroValor(“AAA”);
      dummyEntity.setDummyText(“new text ” + new Date().getTime());

      entityManager.persist(dummyEntity);

      Honestamente não sei falar porque você está tendo esses erros, teria que analisar seu código e no momento não tenho como.

      Desculpe não poder te ajudar mais.

      Obrigado pela visita.

  52. Quando faço merge e duplica valores, onde estou errando o mapeamento?
    Qual a anotação que refere a isto? cascade = CascadeType.ALL ?

      • O Id está preenchido se eu uso persist() ele cria da insert se eu uso merge ele da erro “StaleObjectStateException: Row was updated or deleted by another transaction”, nçao sei o que faço… o exemplo é alterar um endereço de uma loja. OneToOne

        • Daniel, boa noite.

          Veja se seu objeto não está ficando preso em memória e se alguma transação não está sendo finalizada.

          Obrigado pela visita.

  53. Bom dia Hebert.
    Primeiramente, parabéns pelo post, como também pelo site, muito bacana mesmo.
    Mina dúvida é quanto a geração de ID pelo JPA, eu fiz alguns testes, onde utilizo o Eclipselink 2.5.1, a configuração abaixo funciona em Mysql, Postegresql e Oracle.

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY, generator=”gerencia_seq”)
    @Column(name=”idn_gerencia”)
    private int idnGerencia;

    Até achei estranho uma estratégia IDENTITY, trabalhar com SEQUENCE no Oracle similarmente ao AUTO_IMCREMENT do Mysql.
    Procurei na documentação algo sobre essa combinação, mas não encontrei.
    O interesse inicial, era fazer a inserção de 1 em 1 no ID, onde mesmo definindo no @SequenceGenerator um allocationSize para 1, o incremento não foi respeitado.
    Tem uma luz?
    Obrigado.

    • João, boa noite.

      Honestamente achei bastante estranho ter funcionando.

      Eu imagino que ele tenha criado forçadamente o modo de ID no banco de dados.

      Faça um teste criando o banco na mão e faça o teste, e me conte o resultado. [=

      Obrigado pela visita.

  54. Hebert.
    Aqui funcionou perfeitamente o seu exemplo de usar o mesmo Id de uma classe em outras classes, foi o mais bem explicado que achei até o momento.
    Minha dúvida veio após eu gerar o DER no pgModeler. O relacionamento que logicamente estaria certo seria o um pra um, mas é gerado um para muitos.
    Ex.: no seu exemplo o pgModeler geraria um DER ilustrando o relacionamento de OneToMany da classe Dog para a classe DogHouse, sendo que nas entidades do Java está OneToOne.
    Você tem alguma explicação pra isso? Um bug do pgModeler ou teria como consertar apenas usando as anotações? Pois já pesquisei bastante e não achei nada semelhante.
    Belo post,
    Abraço.

  55. O exemplo não saiu muito feliz porque uma “call” tem 2 “celulares” – um é o “chamador” e o outro o “chamado”.

  56. Ola Hebert, parabéns pela iniciativa de compartilhar o seu conhecimento.
    Vamos supor que eu tenha a seguinte situação:

    @Entity
    @IdClass(Classe1PK.class)
    public class Classe1{

    @Id
    @ManyToOne
    @JoinColumn(name=”idOutraClasse”)
    private OutraClasse outraClasse;

    @Id
    private Integer idClasse1;

    //Getters e Setters

    }

    public class Classe1PK{

    private Integer outraClasse;
    private Integer idClasse1;

    //Construtor, Getters e Setters, hash e equals

    }

    @Entity
    public class Classe2{

    @Id
    @ManyToOne
    @JoinColumns({@JoinColumn(name=”idOutraClasse”), @JoinColumn(name=”idClasse1″)})
    private Classe1 classe1;
    @Id
    private Integer idClasse2;

    //Getters e Setters
    }

    Nesta situação, como eu conseguiria mapear a chave composta de Classe1, sendo que ela faz parte também da chave composta da Classe2? É possível fazer isso usando a estratégia do @IdClass?

      • Boa Noite Hebert,

        Obrigado pela dica, li o post acima e entendi a jogada no MapsId.

        Conversando com alguns conhecidos meus, com mais tempo de experiência em JPA, fui aconselhada a simplificar a modelagem, utilizando chave simples nas entidades e definindo os relacionamentos com foreign key. No meu caso, adotei esta estratégia, pois não implicaria em nenhum problema para o meu sistema. Mas acredito que este assunto gere um boa discussão :).

        abraço.

  57. Olá,
    não funciona o InheritanceType.TABLE_PER_CLASS com o GenerationType.AUTO, fui pesquisar e vi que com TABLE_PER_CLASS não se pode usar GenerationType IDENTITY e AUTO (pelo no java 8 com spring 3).

    Usei o GenerationType.TABLE ai funciona no postgres, no entanto, utilizo h2 para testes e o h2 não gera id automaticamente. Tens alguma dica?

    E sugiro fazer a correção no exemplo também para usar TABLE.

    Abs

    • Marcos, boa tarde.

      Realmente bancos em memória tem suas peculiaridades. Honestamente eu criaria um persistence.xml apenas para teste onde eu sobrescreveria esse valor.

      Obrigado pela visita.

  58. Boa noite Hebert, tudo tranquilo?
    Parabéns pelos livros de excelente qualidade do Casa do Código. Assim como na palestra do Infoqbr, espero que eu tenha ajudado com a ração da minhoca ao comprá-los… lol
    Então aí vai, tenho um modelo funcionando(até lhe devo o retorno de um teste quanto a geração de ID, ali acima), perfeitamente. Surgiu a necessidade de expô-lo via webservice, porém estou com dificuldade quando tenho que retornar uma lista de objetos que contem outra lista de objetos. Assinalando as entidades como @Transient, funciona, porém não recupera a lista aninhada de cada objeto.
    Não espero uma explicação do que exatamente fazer, um é possível ta valendo.

    Valeu, abraço.

    • João, boa tarde.

      Honestamente eu criaria um DTO para retornar esse valor, e não retornaria a entidade diretamente.

      Com essa abordagem você desacopla seu modelo da camada de negócio, mas tem a desvantagem de ter que passar o valor da entidade para o DTO.

      Espero ter ajudado. Obrigado pela visita.

  59. Olá Hebert, primeiramente muito obrigado pelo tutorial!

    Olha, eu gostaria de saber como que eu faço para retornar uma lista com todas as ocorrências da entidade PersonDog. Eu tentei o seguinte:

    List lista = new ArrayList();

    SessionFactory sf = HibernateUtil.getSessionFactory();
    Session session = sf.openSession();
    session.beginTransaction();
    lista = (List)session.createQuery(“FROM PersonDog”).list();

    mas fica dando esse erro: “org.hibernate.PropertyAccessException: could not set a field value by reflection setter of”…

    Será que teria como me dar uma luz? Já faz três dias que to procurando como resolver isso e nada ainda… Desde já, obrigado!

    • Leonardo, bom dia.

      O erro que você postou não está muito claro. Eu chutaria que algum valor retornado do banco está diferente do atributo esperado em sua entidade.

      Obrigado pela visita e pelo apoio.

  60. Boa tarde,

    Tenho um aplicação em um servidor linux ubuntu em ingles e os valores monetarios quando digitados corretamente 100,00 quando salvo no banco de dados são convertidos para 1,000.00 acredito que tenha alguma coisa haver com o servidor mais gostaria de saber como configurar a aplicação para evitar este problema.

    • Beto, boa noite.

      Primeiro, me perde a demora em responder. Estou muito pegado no trabalho, para você ter idéia, estou te respondendo dele enquanto um deploy não termina.

      Um jeito fácil e simples de resolver isso é colocar o código Locale.setDefault(new Locale(“en”, “US”)); em algum singleton seu que seja chamado assim que o projeto inicie. Certa vez estava com falta de tempo e essa solução me ajudou muito. (:

      Obrigado pela visita.

  61. Olá Hebert, a abordagem @ManyToMany com campos adicionais está atualizada? Digo isso, pois não consigo entender o motivo de não utilizar @ManyToMany direto e com as tabela adicional que irá ser criada eu adicionar alguns campos. Obrigado

    • João, boa noite.

      Primeiro, me perde a demora em responder. Estou muito pegado no trabalho, para você ter idéia, estou te respondendo dele enquanto um deploy não termina.

      Se você usar o relacionamento direto e adicionar os campos diretamente na tabela, como você faria para o JPA enxergar esses campos? O jeito do JPA conseguir ver esses campos é justamente mapeando a tabela como se fosse uma outra entidade.

      Espero ter sido claro.

      Obrigado pela visita.

      • O que importa é intenção Hebert! Obrigado.
        Correria é bom significa que não falta trabalho… kkk
        Realmente você tem razão depois acabei olhando e analisando com mais calma e faz total sentido a maneira que você explicou.
        Sucesso e obrigado novamente

  62. Boa tarde Hebert, tudo bem ?

    Poderia exemplificar como persistir os objetos Person e Dog neste exemplo (Many to Many com campo adicional) ?

    Estou apanhando a 3 dias.

    Obrigado.

    • Jonathan, boa noite.

      Primeiro, me perde a demora em responder. Estou muito pegado no trabalho, para você ter idéia, estou te respondendo dele enquanto um deploy não termina.

      Honestamente não entendi em que mais eu poderia exemplificar. Qual seu problema/dúvida mais especificamente?

      • Estou tentando persistir PersonDogId mas recebo detached entity passed to persist: teste.Person.

        Obs: Já tenho o Person persistido. Apenas busco-o e faço set dele em PersonDogId.

        O que pode ser ?

  63. Hebert, primeiramente obrigado por compartilhar seu conhecimento e pelo tempo disponibilizado não só para elaborar o conteúdo, mas também pela atenção aos leitores e suas dúvidas.

    Minha curva de aprendizado com JPA foi muito pequena graças ao seu conteúdo.

    Que Deus te ilumine e abençoe.

    • Bruno, boa noite.

      Fico muito feliz em saber que eu consegui ajudar de algum modo.

      Espero continuar te ajudando no que eu puder.

      Até mais, Deus abençoe! o_

  64. Esse post já me ajudou e resolver meu problemas por mais de 10 vezes.
    Meus parabéns. Muito conhecimento em apenas um Post.

  65. Eu tenho um impasse aqui que não consigo resolver.
    Eu tenho uma tabela Usuario a qual possui uma lista de Usuario, ou seja, a entidade relaciona-se consigo mesma.
    Como procedo para resolver isso?
    É uma rede social, ou seja, um Usuario pode adicionar vários Usuários e um Usuário pode ser adicionado várias vezes.
    Pode me ajudar?

    • Jeferson, boa tarde.

      Me desculpe a demora, estive muito ocupado nesse último mês.

      Nesse caso basta você mapear que Usuário tem um OneToMany com uma Lista de usuário.

      Obrigado por tudo e desculpe a demora.

      Att,

  66. Boa tarde tenho uma duvida, como ficaria esse relacionamento abaixo.
    dez de já agradeço a atenção.

    Tabela 1

    Carro
    id_carro
    id_marca

    Tabela 2

    Locadora
    Id_locadora

    Tabela N:N

    Carro_locadora
    Id_carro
    Id_marca
    Id_locadora

    • Marcos, boa tarde.

      Me desculpe a demora, estive muito ocupado nesse último mês.

      Nesse caso você tem que criar uma entidade como CarroTemLocadora e colocar as entidades dentro dela.

      Obrigado por tudo e desculpe a demora.

  67. Seria uma boa prática criar uma terceira classe entity para representar esse relacionamento, e assim criar um relacionamento de Person e Dog para com essa terceira classe??

    • Odenilton, boa tarde.

      Me desculpe a demora, estive muito ocupado nesse último mês.

      Seria caso houvesse a necessidade de adicionar um extra ao relacionamento. Imagine que é necessário ter a data de quando o relacionamento foi criado.

      Obrigado por tudo e desculpe a demora.

    • Alexandre, boa tarde.

      Me desculpe a demora, estive muito ocupado nesse último mês.

      Honestamente não sei te falar nada sobre Netbeans.

      Mas sei que é possível gerar as classes a partir do banco de dados.

      Procure no google por: gerar classes hibernate banco de dados

      Obrigado por tudo e desculpe a demora.

  68. Hebert, boa tarde!

    De antemão, agradeço sua grande colaboração sobre JPA/Hibernate.

    Le seu livro “JPA Eficaz” e, uma coisa me chamou atenção: Neste post, vc nomeia como “attached” as entidades que fazer parte do Persistence Context, já no livro, vc as chama de “managed”. Compreendo que attached e managed possuem o mesmo signifcado no contexto da JPA. Minha dúvida foi porque utilizar essa nomenclatura diferente?

    Grande Abraço!

    • Romero, boa tarde.

      Me desculpe a demora, estive muito ocupado nesse último mês.

      No livro está attached para seguir a convenção da Oracle. O livro veio após o post e realmente achei melhor usar a nomeclatura correta.

      Obrigado por tudo e desculpe a demora.

  69. Hebert, boa tarde.

    Tenho uma classe pessoa composta por uma classe contato, por isso fiz o relacionamento utilizado o OrphanRemoval e estava funcionando perfeitamente.
    Um contato possui vários e-mails e telefones. Tentei utilizar o OrphanRemoval e o cascade mas recebo uma mensagem de erro falando que a classe e-mail não possui o id de contato. Existe algum problema que não seja performance relacionado a utilização do cascade nessas classes?

    • Lucas, boa tarde.

      Me desculpe a demora, estive muito ocupado nesse último mês.

      Honestamente não sei te falar… Nunca ouvi falar desse tipo de problema.

      Obrigado por tudo e desculpe a demora.

  70. Hebert, seu trabalho é de muita ajuda à comunidade. Como sempre, parabéns!

    Estou com uma dúvida. Se eu tiver uma chave composta em Dog como Long id e Person person, qual a abordagem utilizada? É possível que o valor de Long id seja obtido através de @GeneratedValue?

    • Rafael, boa tarde.

      Me desculpe a demora, estive muito ocupado nesse último mês.

      Eu já consegui fazer com @GeneratedValue, mas já vi gente reclamando de não conseguir. Quando eu fiz, eu não tive problema.

      Obrigado por tudo e desculpe a demora.

  71. para o auto relacionamento basta alterar os metodos set das duas classes:

    setPessoa(Pessoa p){
    if(!this.pessoa.equals(p){
    this.pessoa = p;
    this.pessoa.setCelular(this);
    }
    }

    setCelular(Celular c){
    if(!this.celular.equals(c)){
    this.celular = c;
    this.celular.setPessoa(this);
    }
    }

  72. Bom dia,

    cai num problema onde tenho uma tabela perfil e mais outras duas tabelas funcionario e usuario, seriam três tabelas mais a associativa gerada a partir das outras três, como ficaria uma mapeamento com três ou mais tabelas?

    Obrigado mais uma vez!!

Leave a Comment