2011-05-28 11 views
53

Aunque esta pregunta se me ha hecho muchas veces y ya he utilizado todas las sugerencias, sigo recibiendo este error.org.hibernate.MappingException: No se pudo determinar el tipo para: java.util.Set

La User.java es

@Entity 
@Table(name = "USER") 
public class User implements UserDetails, Serializable { 

    private static final long serialVersionUID = 2L; 

    @Id 
    @Column(name = "USER_ID") 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private long id; 
    @Column(name = "USERNAME") 
    private String username; 
    @Column(name = "PASSWORD") 
    private String password; 
    @Column(name = "NAME") 
    private String name; 
    @Column(name = "EMAIL") 
    private String email; 
    @Column(name = "LOCKED") 
    private boolean locked; 
    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER) 
    @ElementCollection(targetClass=Role.class) 
    @Column(name = "ROLE_ID") 
    private Set<Role> roles; 

    @Override 
    public GrantedAuthority[] getAuthorities() { 
     List<GrantedAuthorityImpl> list = new ArrayList<GrantedAuthorityImpl>(0); 
     for (Role role : roles) { 
      list.add(new GrantedAuthorityImpl(role.getRole())); 
     } 
     return (GrantedAuthority[]) list.toArray(new GrantedAuthority[list.size()]); 
    } 

    @Override 
    public boolean isAccountNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isAccountNonLocked() { 
     return !isLocked(); 
    } 

    @Override 
    public boolean isCredentialsNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isEnabled() { 
     return true; 
    } 

    public long getId() { 
     return id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public boolean isLocked() { 
     return locked; 
    } 

    public void setLocked(boolean locked) { 
     this.locked = locked; 
    } 

    @Override 
    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @Override 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public void setRoles(Set<Role> roles) { 
     this.roles = roles; 
    } 

    public Set<Role> getRoles() { 
     return roles; 
    } 
} 

Y el Role.java es

@Entity 
@Table(name="ROLE") 
public class Role implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="ROLE_ID") 
    private long id; 
    @Column(name="USERNAME") 
    private String username; 
    @Column(name="ROLE") 
    private String role; 


    public long getId() { 
     return id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public String getRole() { 
     return role; 
    } 

    public void setRole(String role) { 
     this.role = role; 
    } 
} 

Este es mi primer intento en la anotación de hibernación con APP. Entonces cualquier sugerencia será de mucha ayuda.

Para hibernar dependencias del pom.xml son:

<dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate</artifactId> 
     <version>3.5.4-Final</version> 
     <type>pom</type> 
     <scope>compile</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-annotations</artifactId> 
     <version>3.5.4-Final</version> 
     <type>jar</type> 
     <scope>compile</scope> 
    </dependency> 

    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-core</artifactId> 
     <version>3.5.4-Final</version> 
     <type>jar</type> 
     <scope>compile</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-validator</artifactId> 
     <version>3.1.0.GA</version> 
     <type>jar</type> 
     <scope>compile</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>3.5.4-Final</version> 
     <type>jar</type> 
     <scope>compile</scope> 
    </dependency> 

no tengo ninguna pista sobre el fallo.

Gracias.

+3

Solo debe usar @ManyToOne con @JoinColumn en este caso, ya que Role es una entidad. Utiliza @ElementCollection y @Column solo cuando la colección contiene tipos básicos (Entero, Cadena, Fecha, etc.) o tipos incrustables. Vea ejemplos en la especificación de JPA 2.0 si lo desea. Está combinando anotaciones que nunca se usan juntas y esta podría ser la fuente del problema. –

Respuesta

1

Solución:

@Entity 
@Table(name = "USER") 
@Access(AccessType.FIELD) 
public class User implements UserDetails, Serializable { 

    private static final long serialVersionUID = 2L; 

    @Id 
    @Column(name = "USER_ID", updatable=false, nullable=false) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private long id; 

    @Column(name = "USERNAME") 
    private String username; 

    @Column(name = "PASSWORD") 
    private String password; 

    @Column(name = "NAME") 
    private String name; 

    @Column(name = "EMAIL") 
    private String email; 

    @Column(name = "LOCKED") 
    private boolean locked; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, targetEntity = Role.class) 
    @JoinTable(name = "USER_ROLE", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "ROLE_ID") }) 
    private Set<Role> roles; 

    @Override 
    public GrantedAuthority[] getAuthorities() { 
     List<GrantedAuthorityImpl> list = new ArrayList<GrantedAuthorityImpl>(0); 
     for (Role role : roles) { 
      list.add(new GrantedAuthorityImpl(role.getRole())); 
     } 
     return (GrantedAuthority[]) list.toArray(new GrantedAuthority[list.size()]); 
    } 

    @Override 
    public boolean isAccountNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isAccountNonLocked() { 
     return !isLocked(); 
    } 

    @Override 
    public boolean isCredentialsNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isEnabled() { 
     return true; 
    } 

    public long getId() { 
     return id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    @Override 
    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @Override 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public boolean isLocked() { 
     return locked; 
    } 

    public void setLocked(boolean locked) { 
     this.locked = locked; 
    } 

    public Set<Role> getRoles() { 
     return roles; 
    } 

    public void setRoles(Set<Role> roles) { 
     this.roles = roles; 
    } 
} 

Role.java mismo que el anterior.

+70

Sería mucho mejor si dijera qué necesita cambiarse (y explique por qué) en lugar de publicar el código completo. Uno tiene que comparar dos archivos línea por línea para encontrar la diferencia. – Jamol

+20

Al comparar los archivos, he encontrado las siguientes diferencias: 1. Ha agregado @Access (AccessType.FIELD) a la clase 2. @ElementColection en los roles del Conjunto ha sido reemplazado por @JoinTable (...) – Marco

14

Supongo que está utilizando un Set<Role> en la clase User anotado con @OneToMany. Lo que significa que uno User tiene muchos Role s. Pero en el mismo campo usa la anotación @Column que no tiene sentido. Las relaciones uno a muchos se administran usando una tabla de combinación separada o una columna de unión en muchos lados, que en este caso sería la clase Función. Usar @JoinColumn en lugar de @Column probablemente solucionaría el problema, pero parece ser semánticamente incorrecto. Supongo que la relación entre el rol y el usuario debe ser de muchos a muchos.

+0

@ElementCollection también se ve extraño allí. ¿Cuál es el propósito? – whiskeysierra

+0

cambiar a @OneToMany (cascade = CascadeType.ALL, targetEntity = Role.class, mappedBy = "usuario", fetch = FetchType.EAGER) \t @JoinColumn (name = "ROLE_ID") \t privadas Set papeles; no resolvió el problema Vi otro hilo que se recomienda usar @ElementCollection y es por eso que lo uso. –

+1

El elementCollection no es el usado para los componentes? ¿Objetos cuyo ciclo de vida sigue a la entidad propietaria? – Konstantin

4

No dice que su asignación es correcta o incorrecta, pero creo que hibernate quiere una instancia del conjunto donde declara el campo.

@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER) 
//@ElementCollection(targetClass=Role.class) 
@Column(name = "ROLE_ID") 
private Set<Role> roles = new HashSet<Role>(); 
+1

Lo hice después de su instrucción. Pero no resolvió. Si quieres, puedo publicar stacktrace completo. –

+2

No es necesario utilizar @ElementCollection en el conjunto de roles porque el rol es una entidad. Solo debe usar @ManyToOne en este caso. La especificación JPA 2.0 establece claramente que @EllementCollection es para tipos básicos e incrustables. Además, debe especificar la información de columna utilizando @JoinColumn, no @Column. Este último se usaría con @ElementCollection, pero no con @ManyToOne. –

+0

Claro, publique stacktrace y edalorzo Sé que está en lo correcto – Konstantin

35

Añadiendo el campo @ElementCollection a la Lista resolvieron este problema:

@Column 
@ElementCollection(targetClass=Integer.class) 
private List<Integer> countries; 
+1

What ? Esto no se relaciona con la pregunta. – dwjohnston

+0

Lo resolvió para mí sin siquiera especificar targetClass :) – hughjdavey

54

Tengo el mismo problema con @ManyToOne columna. Fue resuelto ... de manera estúpida. Tenía todas las otras anotaciones para los métodos públicos getter, porque fueron anuladas de la clase principal. Pero el último campo fue anotado para variable privada como en todas las otras clases en mi proyecto. Así que obtuve el mismo MappingException sin el motivo.

Solución: Coloqué todas las anotaciones en métodos public getter. Supongo que Hibernate no puede manejar casos, cuando las anotaciones para campos privados y public getters se mezclan en una clase.

+0

Lo resolvió para mí también – Cesar

+0

Debe marcarse como la mejor respuesta – 1020rpz

0

tuve un problema similar donde estaba recibiendo un error para un miembro de la clase que no se asigna a la columna de la db, que era sólo un soporte para una Lista de otra entidad. Cambié List a ArrayList y el error desapareció. Lo sé, realmente no debería hacer eso en una entidad mapeada, y eso es para lo que son las DTO. Solo quería compartir en caso de que alguien encuentre este hilo y las respuestas anteriores no se apliquen ni ayuden.

2

Tuve este problema hoy y descubrí que inadvertidamente dejé la anotación @ManyToMany encima de la anotación @JoinTable.

+0

Wow Me pasé todo el día tratando de solucionar mi problema y fue exactamente esto. Soy un idiota. – Dom

1

Tuve un problema similar Encontré el problema que estaba mezclando las anotaciones algunas de ellas por encima de los atributos y algunas de ellas por encima de los métodos públicos. Acabo de poner todos ellos por encima de los atributos y funciona.

Cuestiones relacionadas