it-swarm.com.de

org.hibernate.MappingException: Der Typ für: Java.util.Set konnte nicht ermittelt werden

Diese Frage wurde zwar oft gestellt und ich habe bereits den ganzen Vorschlag verwendet, aber ich bekomme immer noch diesen Fehler.

Die User.Java ist

@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;
    }
}

Und die Rolle.Java ist

@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;
    }
}

Dies ist mein erster Versuch, die Annotation mit JPA in den Ruhezustand zu versetzen. Alle Vorschläge werden also sehr hilfreich sein. 

Für den Ruhezustand sind die Abhängigkeiten von pom.xml:

    <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>

Ich habe keine Ahnung von der Schuld.

Vielen Dank.

70
Tapas Bose

Lösung:

@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;
    }
}

Rolle.Java wie oben.

5
Tapas Bose

Ich habe das gleiche Problem mit @ManyToOne Spalte. Es wurde gelöst ... auf dumme Weise. Ich hatte alle anderen Anmerkungen für öffentliche Getter-Methoden, weil sie von der übergeordneten Klasse überschrieben wurden. Das letzte Feld wurde jedoch wie in allen anderen Klassen in meinem Projekt für die private Variable kommentiert. Also bekam ich dasselbe MappingException ohne den Grund.

Lösung: Ich habe alle Anmerkungen bei öffentlichen Getter-Methoden platziert. Ich vermute, Hibernate kann keine Fälle behandeln, wenn Anmerkungen für private Felder und öffentliche Getter in einer Klasse gemischt sind.

76
Avadhuta

Durch das Hinzufügen des @ElementCollection zum Feld "Liste" wurde dieses Problem behoben:

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

Ich vermute, Sie verwenden einen Set<Role> in der User-Klasse, der mit @OneToMany versehen ist. Was bedeutet, dass User viele Roles hat. Für dasselbe Feld verwenden Sie jedoch die @Column-Anmerkung, was keinen Sinn macht. One-to-Many-Beziehungen werden mithilfe einer separaten Join-Tabelle oder einer Join-Spalte auf der Many-Seite verwaltet, die in diesem Fall die Rollenklasse wäre. Die Verwendung von @JoinColumn anstelle von @Column würde das Problem wahrscheinlich beheben, aber es scheint semantisch falsch zu sein. Ich denke, dass die Beziehung zwischen Rolle und Benutzer viele zu viele sein sollte.

15
whiskeysierra

Ich sage nicht, dass Ihr Mapping richtig oder falsch ist, aber ich glaube, der Ruhezustand möchte eine Instanz des Satzes, in der Sie das Feld deklarieren.

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

Hatte dieses Problem gerade heute und stellte fest, dass ich die Annotation @ManyToMany über der Annotation @JoinTable versehentlich aufgegeben habe. 

4
Mark

Ich hatte ein ähnliches Problem. Ich fand das Problem, dass ich die Anmerkungen einige über den Attributen und einige über öffentliche Methoden mischte. Ich habe alle über Attribute gesetzt und es funktioniert.

2

Sie müssen möglicherweise nur @Transient-Anmerkungen zu Rollen hinzufügen, um den Satz nicht zu serialisieren.

Warum hat Java vorübergehende Felder?

1
Mark

Ich hatte ein ähnliches Problem, bei dem ich einen Fehler für ein Mitglied der Klasse erhielt, das nicht der Db-Spalte zugeordnet war. Es war lediglich ein Halter für eine Liste einer anderen Entität. Ich habe List in ArrayList geändert und der Fehler ist verschwunden. Ich weiß, ich sollte das wirklich nicht in einer gemappten Entität machen, und dafür sind DTOs gedacht. Ich wollte nur teilen, falls jemand diesen Thread findet und die obigen Antworten nicht zutreffen oder helfen.

0
Ginja Ninja