Olá Pessoal, tudo bom?
Hoje iremos falar sobre um erro de Mapeamento de Entidades JPA, mais especificamente da exception org.hibernate.AnnotationException: Collection has neither generic type or OneToMany.targetEntity() defined: ClasseOrigem.collection.
Descrição do Erro
A especificação do JPA necessita que ao mapear uma collections seja utilizado generics para indicar ao Java qual é a entidade que essa lista armazena, auxiliando na obtenção, pelo JPA, das chaves primárias da entidade referenciada. Assim vamos supor o seguinte exemplo do código abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package br.com.mauda.example.model; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; @Entity public class Artista implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nome; @OneToMany(mappedBy = "artista") private List musicas = new ArrayList(); public Artista(){ } //outros atributos, métodos e construtores } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package br.com.mauda.example.model; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Musica implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nome; @ManyToOne @JoinColumn(name="ID_ARTISTA") private Artista artista; //outros atributos, métodos e construtores } |
Perceba que o mapeamento do atributo musicas da classe Artista foi realizado sem a utilização de generics, conforme a linha destacada. Com isso ocorrerá um erro com a seguinte stack trace:
org.hibernate.AnnotationException: Collection has neither generic type or OneToMany.targetEntity() defined: br.com.mauda.example.model.Artista.musicas
at org.hibernate.cfg.annotations.CollectionBinder.getCollectionType(CollectionBinder.java:644)
at org.hibernate.cfg.annotations.CollectionBinder.bind(CollectionBinder.java:537)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2084)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:895)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:728)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3568)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3522)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1379)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1784)
Solução
Existem duas soluções para corrigir esse problema
1) A exception mencionada ocorre devido a falta de informação para o JPA de qual é a classe Destino que será abrigada na Collection, assim ao inserir os generics conforme a linha destacada do código abaixo, o problema será corrigido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package br.com.mauda.example.model; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; @Entity public class Artista implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nome; @OneToMany(mappedBy = "artista") private List<Musica> musicas = new ArrayList<Musica>(); public Artista(){ } //outros atributos, métodos e construtores } |
2) Outra solução, está relacionada com o impedimento da inserção de generics, por exemplo, a utilização de versões anteriores do Java 5, onde ainda não existia o generics. Para esses casos existe o element targetEntity ((Element targetEntity – API Java EE 7 – Link)), o qual torna possível indicar ao JPA qual é a entidade que a collection irá conter. O código abaixo indica como ficaria essa solução:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package br.com.mauda.example.model; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; @Entity public class Artista implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nome; @OneToMany(mappedBy = "artista", targetEntity=Musica.class) private List musicas = new ArrayList(); public Artista(){ } //outros atributos, métodos e construtores } |
finally{
Caso você achou mais alguma solução para essa exception, por favor deixe nos comentários abaixo!
Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!
Até um próximo post!
Leave a Reply