org.hibernate.MappingException:无法确定类型:java.util.Set [重复]
Posted
技术标签:
【中文标题】org.hibernate.MappingException:无法确定类型:java.util.Set [重复]【英文标题】:org.hibernate.MappingException: Could not determine type for: java.util.Set [duplicate] 【发布时间】:2011-09-04 01:57:15 【问题描述】:虽然这个问题被问了很多次并且我已经使用了所有的建议,但我仍然收到这个错误。
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 与 @JoinColumn 一起使用,因为 Role 是一个实体。仅当集合包含基本类型(整数、字符串、日期等)或可嵌入类型时,才使用 @ElementCollection 和 @Column。如果需要,请参阅 JPA 2.0 规范中的示例。您正在组合从未一起使用的注释,这可能是问题的根源。 【参考方案1】:@ManyToOne
列也有同样的问题。它被解决了......以愚蠢的方式。我有公共 getter 方法的所有其他注释,因为它们被父类覆盖。但是最后一个字段被注释为私有变量,就像我项目中的所有其他类一样。所以我毫无理由地得到了相同的MappingException
。
解决方案:我将所有注释都放在公共 getter 方法中。我想,当私有字段和公共 getter 的注释混合在一个类中时,Hibernate 无法处理这种情况。
【讨论】:
【参考方案2】:将@ElementCollection
添加到列表字段解决了这个问题:
@Column
@ElementCollection(targetClass=Integer.class)
private List<Integer> countries;
【讨论】:
什么?这与问题无关。 为我解决了这个问题,甚至没有指定 targetClass :)(targetClass=Integer.class)
在这种情况下不需要。仅当您的列表是泛型类型时才需要这样做
您不需要在每个数据成员上默认指定@Column
@Column
【参考方案3】:
我猜你在User
类中使用Set<Role>
,并用@OneToMany
注释。这意味着一个User
有许多Role
s。但是在同一个字段上,您使用 @Column
注释,这是没有意义的。一对多关系使用单独的连接表或多方连接列进行管理,在本例中为 Role 类。使用@JoinColumn
而不是@Column
可能会解决这个问题,但它似乎在语义上是错误的。我猜角色和用户之间的关系应该是多对多的。
【讨论】:
@ElementCollection 在那里看起来也很奇怪。目的是什么? 更改为 @OneToMany(cascade=CascadeType.ALL, targetEntity=Role.class, mappedBy="user", fetch = FetchType.EAGER) @JoinColumn(name="ROLE_ID") 私有集今天刚遇到这个问题,发现我无意中遗漏了@JoinTable 注释上方的@ManyToMany 注释。
【讨论】:
【参考方案5】:不是说你的映射是正确还是错误,但我认为 hibernate 想要一个你声明字段的集合的实例。
@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
//@ElementCollection(targetClass=Role.class)
@Column(name = "ROLE_ID")
private Set<Role> roles = new HashSet<Role>();
【讨论】:
我是按照你的指示去做的。但没有解决。如果你愿意,我可以发布完整的堆栈跟踪。 角色集中不需要使用@ElementCollection,因为角色是一个实体。在这种情况下,您只能使用 @ManyToOne。 JPA 2.0 规范明确指出 @EllementCollection 用于基本类型和可嵌入对象。此外,您必须使用@JoinColumn 指定列信息,而不是@Column。后者将与@ElementCollection 一起使用,但不能与@ManyToOne 一起使用。 确定发布堆栈跟踪和 edalorzo 我知道你是对的【参考方案6】:我遇到了类似的问题,我发现我将注释混合在一起的问题,其中一些在属性之上,一些在公共方法之上。我只是将它们全部放在属性之上,它就可以工作。
【讨论】:
这里也一样。你让我免于数小时的调试。谢谢!【参考方案7】:解决方案:
@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 同上。
【讨论】:
如果您告诉需要更改的内容(并解释原因)而不是发布完整的代码会更好。必须逐行比较两个文件才能发现差异。 比较文件,我发现以下差异: 1.他在类中添加了@Access(AccessType.FIELD) 2. Set您可能只需要在角色上添加@Transient
注释即可不序列化集合。
Why does Java have transient fields?
【讨论】:
【参考方案9】:我遇到了一个类似的问题,我收到了一个未映射到 db 列的类成员的错误,它只是另一个实体列表的持有者。我将 List 更改为 ArrayList 并且错误消失了。我知道,我真的不应该在映射实体中这样做,这就是 DTO 的用途。只是想分享一下,以防有人发现这个帖子并且上面的答案不适用或没有帮助。
【讨论】:
以上是关于org.hibernate.MappingException:无法确定类型:java.util.Set [重复]的主要内容,如果未能解决你的问题,请参考以下文章