Подтвердить что ты не робот

Org.hibernate.MappingException: Не удалось определить тип для: java.util.Set

Хотя этот вопрос задавался много раз, и я уже использовал все предложения, но все же получаю эту ошибку.

Пользователь User.java

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

И Role.java

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

Это моя первая попытка аннотации спящего режима с JPA. Поэтому любые предложения будут очень полезными.

Для спящего режима зависимости 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>

У меня нет никакой информации об ошибке.

Спасибо.

4b9b3361

Ответ 1

Решение:

@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, как указано выше.

Ответ 2

У меня такая же проблема с столбцом @ManyToOne. Это было решено... глупо. У меня были все другие аннотации для общедоступных методов getter, потому что они были переопределены из родительского класса. Но последнее поле было аннотировано для частной переменной, как и во всех других классах моего проекта. Таким образом, я получил тот же MappingException без причины.

Решение. Я разместил все аннотации в общедоступных методах получения. Я полагаю, Hibernate не может обрабатывать случаи, когда аннотации для частных полей и публичных геттеров смешиваются в одном классе.

Ответ 3

Добавление поля @ElementCollection в список позволило решить эту проблему:

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

Ответ 4

Я предполагаю, что вы используете Set<Role> в классе User, аннотированный с помощью @OneToMany. Это означает, что один User имеет много Role s. Но в том же поле вы используете аннотацию @Column, которая не имеет смысла. Управление "один ко многим" управляется с помощью отдельной таблицы соединений или столбца объединения на стороне, которая в этом случае будет классом Role. Использование @JoinColumn вместо @Column, вероятно, устранит проблему, но кажется семантически неправильным. Я полагаю, что отношение между ролью и пользователем должно быть много-ко-многим.

Ответ 5

Не сказать, что ваше сопоставление правильное или неправильное, но я думаю, что hibernate хочет экземпляр набора, в котором вы объявляете поле.

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

Ответ 7

Если бы эта проблема появилась сегодня и обнаружила, что я случайно отказался от аннотации @ManyToMany над аннотацией @JoinTable.

Ответ 8

У меня была аналогичная проблема, я обнаружил, что я смешивал аннотации с некоторыми из них над атрибутами, а некоторые из них - над общедоступными методами. Я просто положил все из них выше атрибутов, и он работает.

Ответ 9

У меня была аналогичная проблема, когда я получал сообщение об ошибке для члена класса, который не был сопоставлен столбцу db, он был просто владельцем списка другого объекта. Я изменил List на ArrayList, и ошибка исчезла. Я знаю, я действительно не должен этого делать в сопоставленной сущности и для чего нужен DTO. Просто хотел поделиться, если кто-то найдет этот поток, и ответы выше не применяются или не помогают.