2011-05-28 62 views
53

雖然這個問題問了很多次,我已經使用了所有的建議,但我仍然得到這個錯誤。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> 

我不知道故障的線索。

謝謝。

+3

你必須在這種情況下,因爲角色是一個實體只能使用@ManyToOne與@JoinColumn。您可以使用@ElementCollection和@Column只有當集合包含基本類型(整數,字符串,日期,ECT)或嵌入類型。如果需要,請參閱JPA 2.0規範中的示例。您將註釋從未結合使用,這可能是問題的根源。 – 2011-05-29 13:37:22

回答

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如上相同。

+70

這將是好得多,如果你告訴需要改變什麼(解釋),而不是發佈完整的代碼。必須逐行比較兩個文件以找出差異。 – Jamol 2011-07-13 05:23:05

+20

文件相比較,我發現以下區別:1。 他補充@Access(AccessType.FIELD)對類 2. @ElementColection上設置角色已被替換@JoinTable(...) – Marco 2012-03-21 22:20:18

14

我的猜測是你在User類中使用了Set<Role>,這個類用@OneToMany註解。這意味着一個User有許多Role s。但是在同一個領域,您使用的是無意義的註釋。一對多關係在多方面使用單獨的連接表或連接列進行管理,在這種情況下,這將是Role類。使用@JoinColumn而不是@Column可能會解決這個問題,但它在語義上似乎是錯誤的。我想角色和用戶之間的關係應該是多對多的。

+0

@ElementCollection在那裏也很奇怪。目的是什麼? – whiskeysierra 2011-05-28 20:20:32

+0

更改爲@OneToMany(級聯= CascadeType.ALL,targetEntity = Role.class,的mappedBy = 「用戶」,取= FetchType.EAGER)\t @JoinColumn(name = 「ROLE_ID」) \t私訂角色;沒有解決問題。我看到其他一些建議使用@ElementCollection的線程,這就是我使用它的原因。 – 2011-05-28 20:33:26

+1

elementCollection不是用於組件的嗎?擁有實體的生命週期的對象? – Konstantin 2011-05-28 21:26:50

4

不是說你的映射是正確的還是錯誤的,但我認爲hibernate需要一個聲明該字段的集合的實例。

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

我在你的指導後做了。但沒有解決。如果你想我可以發佈完整的堆棧跟蹤。 – 2011-05-28 21:16:20

+2

因爲角色是實體,所以不需要在角色集中使用@ElementCollection。在這種情況下,您只能使用@ManyToOne。 JPA 2.0規範明確指出@EllementCollection適用於基本類型和可嵌入。另外,您必須使用@JoinColumn而不是@Column來指定列信息。後者將與@ElementCollection一起使用,但不能與@ManyToOne一起使用。 – 2011-05-29 13:34:13

+0

當然張貼堆棧跟蹤和edalorzo我知道你是正確的 – Konstantin 2011-05-29 19:20:23

35

添加@ElementCollection列表字段解決了這個問題:

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

什麼?這與問題無關。 – dwjohnston 2016-07-25 01:05:08

+0

解決了這個問題對我來說,甚至沒有指定targetClass :) – hughjdavey 2018-01-18 13:28:22

54

我得到了同樣的問題@ManyToOne列。它以愚蠢的方式解決了。我有公共getter方法的所有其他註釋,因爲它們被父類覆蓋。但是最後一個字段被註釋爲私有變量,就像我的項目中所有其他類一樣。所以我沒有理由得到了相同的MappingException

解決方案:我將所有註釋放在公共getter方法中。我想,當私人領域的註解和公共getter混合在一個類中時,Hibernate不能處理案例。

+0

解決了這個問題對我來說也 – Cesar 2017-08-21 12:17:36

+0

應該被標記爲最佳答案 – 1020rpz 2018-02-11 15:38:35

0

我有一個類似的問題,我在那裏得到一個錯誤在類中的成員,這不是映射到數據庫列,這只是另一個實體列表的持有人。我將List更改爲ArrayList,錯誤消失了。我知道,我真的不應該在一個地圖實體中這樣做,而這正是DTO的目的。只是想分享的情況下,有人發現這個線程和上面的答案不適用或幫助。

2

有了這個問題,就在今天,發現我無意中不放過@JoinTable註解上方@ManyToMany註解。

+0

哇,我一整天都在試圖解決我的問題,也就是這。我真是個白癡。 – Dom 2018-01-05 20:16:07

1

我有類似的問題,我發現這個問題我是混合註釋其中一些上面的屬性,其中一些上面公開的方法。我只是把它們全部放在屬性上面並且它可以工作。

相關問題