Program Club

org.hibernate.MappingException : java.util.Set에 대한 유형을 판별 할 수 없습니다.

proclub 2020. 10. 9. 12:34
반응형

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>

나는 잘못에 대한 단서가 없습니다.

감사.


나는 @ManyToOne칼럼 과 같은 문제가 있습니다. 해결되었습니다 ... 어리석은 방식으로. 공개 getter 메서드에 대한 다른 모든 주석은 부모 클래스에서 재정의 되었기 때문입니다. 그러나 마지막 필드는 내 프로젝트의 다른 모든 클래스와 마찬가지로 개인 변수에 대한 주석이 추가되었습니다. 그래서 MappingException이유없이 똑같은 것을 얻었습니다 .

솔루션 : 모든 주석을 공개 getter 메서드에 배치했습니다. Hibernate는 private 필드와 public getter에 대한 주석이 하나의 클래스에 혼합되어있는 경우를 처리 할 수 ​​없다고 생각합니다.


@ElementCollection목록 필드에를 추가하면 이 문제가 해결되었습니다.

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

내 생각 엔 당신이를 사용하는 것입니다 Set<Role>User주석 클래스 @OneToMany. 이는 하나 User가 많은 것을 의미 Role합니다. 그러나 동일한 필드에서 @Column의미가없는 주석을 사용합니다 . 일대 다 관계는 별도의 조인 테이블 또는 다측의 조인 열을 사용하여 관리되며,이 경우 역할 클래스가됩니다. @JoinColumn대신 사용 @Column하면 문제가 해결 될 수 있지만 의미 상 잘못된 것 같습니다. 역할과 사용자의 관계는 다 대다 여야한다고 생각합니다.


이 문제가 바로 오늘 있었는데 실수로 @JoinTable 주석 위에 @ManyToMany 주석을 남겼 음을 발견했습니다.


해결책:

@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는 위와 같습니다.


매핑이 정확하거나 잘못되었다고 말하지는 않지만 최대 절전 모드는 필드를 선언하는 집합의 인스턴스를 원한다고 생각합니다.

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

I had similar problem I found the issue I was mixing the annotations some of them above the attributes and some of them above public methods. I just put all of them above attributes and it works.


You may just need to add @Transient annotations on roles to not serialize the set.

Why does Java have transient fields?


I had a similar issue where I was getting an error for a member in the class that wasn't mapped to the db column, it was just a holder for a List of another entity. I changed List to ArrayList and the error went away. I know, I really shouldn't do that in a mapped entity, and that's what DTO's are for. Just wanted to share in case someone finds this thread and the answers above don't apply or help.

참고URL : https://stackoverflow.com/questions/6164123/org-hibernate-mappingexception-could-not-determine-type-for-java-util-set

반응형