Bien que cette question ait été posée à plusieurs reprises et que j'ai déjà utilisé toute la suggestion, je reçois néanmoins cette erreur.
Le User.Java est
@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;
}
}
Et le Role.Java est
@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;
}
}
C’est la première fois que je tente une annotation en veille prolongée avec JPA. Donc, toutes les suggestions seront très utiles.
Pour hibernate, les dépendances de pom.xml sont les suivantes:
<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>
Je n'ai aucune idée de la faute.
Merci.
Solution:
@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 comme ci-dessus.
J'ai le même problème avec la colonne @ManyToOne
. C'était résolu ... d'une manière stupide. J'avais toutes les autres annotations pour les méthodes getter publiques, car elles avaient été remplacées par la classe parent. Mais le dernier champ a été annoté pour la variable privée, comme dans toutes les autres classes de mon projet. J'ai donc la même MappingException
sans la raison.
Solution: J'ai placé toutes les annotations dans les méthodes de lecture publiques. Je suppose qu'Hibernate ne peut pas gérer les cas où des annotations pour des champs privés et des getters publics sont mélangés dans une classe.
L'ajout du @ElementCollection
au champ Liste a résolu ce problème:
@Column
@ElementCollection(targetClass=Integer.class)
private List<Integer> countries;
Je suppose que vous utilisez un Set<Role>
dans la classe User
annotée avec @OneToMany
. Ce qui signifie qu'une User
a plusieurs Role
s. Mais sur le même champ, vous utilisez l'annotation @Column
qui n'a aucun sens. Les relations un à plusieurs sont gérées à l'aide d'une table de jointure séparée ou d'une colonne de jointure du côté multiple, qui dans ce cas serait la classe de rôle. Utiliser @JoinColumn
au lieu de @Column
résoudrait probablement le problème, mais cela semble sémantiquement faux. J'imagine que la relation entre le rôle et l'utilisateur devrait être multiple.
Ne dites pas que votre mappage est correct ou faux, mais je pense qu'Hibernate souhaite une instance de l'ensemble où vous déclarez le champ.
@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
//@ElementCollection(targetClass=Role.class)
@Column(name = "ROLE_ID")
private Set<Role> roles = new HashSet<Role>();
Si ce problème venait d’aujourd’hui et que j’avais découvert par inadvertance que j’avais omis l’annotation @ManyToMany au-dessus de l’annotation @JoinTable.
J'avais un problème similaire. J'ai trouvé le problème en mélangeant les annotations, certaines au-dessus des attributs et certaines au-dessus des méthodes publiques. Je viens de mettre tous les ci-dessus des attributs et cela fonctionne.
Vous devrez peut-être simplement ajouter des annotations @Transient
sur les rôles pour ne pas sérialiser l'ensemble.
J'ai eu un problème similaire où je recevais une erreur pour un membre de la classe qui n'a pas été mappé à la colonne de base de données, il s'agissait simplement d'un titulaire pour la liste d'une autre entité. J'ai changé List en ArrayList et l'erreur est partie. Je sais, je ne devrais vraiment pas faire cela dans une entité cartographiée, et c'est à cela que servent les DTO. Je voulais juste partager si quelqu'un trouve ce fil et que les réponses ci-dessus ne s'appliquent pas et ne les aident pas.