2017-03-27 52 views
0

我想有相同的领域类的2场在我的实体,我得到这个错误:JPA实体与同类型的两个字段

org.hibernate.MappingException: Could not determine type for: com.packt.webapp.domain.User, at table: opinions, for columns: [org.hibernate.mapping.Column(author)]

我的实体:

@Entity 
@Table(name="opinions") 
public class Opinion { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 
    @NotNull 
    private String text; 
    @NotNull 
    private String date; 
    @ManyToOne 
    @JoinColumn(name="commented_user") 
    private User writtenTo; 
    private User author; 

@Entity 
@Table(name="user") 
public class User { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 
    private String username; 
    private String password; 
    @OneToMany(mappedBy="writtenTo") 
    private List<Opinion> opinions; 

我只是想将意见映射到评论用户和评论的存储作者author字段中。当我删除author字段时,一切正常。这个例子有什么不对?

+0

为什么不从'User'中删除'List views'并用JPQL查询? – michaeak

+0

您是否试图为Written和作者使用ManyToOne批注? – jmw5598

+0

@michaeak你的意思是有2个简单的字段,如:'commentedUser'和'author'?这是个好主意:)但我只是想知道为什么我的代码不工作。 – crooked

回答

1

这是抱怨,它不知道如何映射author字段。您可以提供类似于您映射writtenTo的映射。一个意见有一个作者和一个作者可以撰写很多意见。

如果您想忽略映射字段,请使用@Transient对其进行注释。瞬态注释防止现场被保存到数据库,否则你必须映射它,像这样:

意见实体:

@Entity 
@Table(name="opinions") 
public class Opinion { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @NotNull 
    private String text; 

    @NotNull 
    private String date; 

    @ManyToOne 
    @JoinColumn(name="commented_user") 
    private User writtenTo; 

    // map author to User entity 
    @ManyToOne 
    @JoinColumn(name="authored_user") 
    private User author; 

    // getters and setters 
} 

用户实体:

@Entity 
@Table(name="user") 
public class User { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    private String username; 

    private String password; 

    @OneToMany(mappedBy="writtenTo") 
    private List<Opinion> opinions; 

    // map opinions to the author 
    @OneToMany(mappedBy="author") 
    private List<Opinion> authoredOpinions; 

    // getters and setters 
} 
+1

请注意,除非重叠到预先存在的SQL模式上,否则'@ JoinColumn'通常是不必要的。 – chrylis

1

请尝试注释也作者?

@ManyToOne 
@JoinColumn(name="author") 
private User author; 
0

只是应用@ManyToOne两个用户字段的注释。

@ManyToOne 
@JoinColumn(name="commented_user") 
private User writtenTo; 
@ManyToOne 
@JoinColumn(name="author") 
private User author; 

但是这样的问题有更灵活的解决方案。用@ManyToMany替换@OneToMany和@ManyToOne关系。创建一个用户和一个角色实体(带有特定字段的实体的后代)。用户可以有许多角色(作家,作者等),角色可以由许多用户播放。在这种情况下,您可以改变主意并动态创建/删除/附加/分离角色,而无需在现有表上更改任何数据结构。

@Entity 
public class User 
{ 
    @Id 
    private Long id; 
    @Column 
    private String name; 
    @ManyToMany 
    @JoinTable(
     name="User_Role", 
     [email protected](name="UserID", referencedColumnName="ID"), 
     [email protected](name="RoleID", referencedColumnName="ID")) 
    private List<Role> roles; 
} 

@Entity 
public class Role 
{ 
    @Id 
    private Long id; 
    @Column 
    private String name; 
    @ManyToMany(mappedBy="roles") 
    private List<User> users; 
} 

,你可以得到/使用实用工具类的角色ID /名称检查用户角色:

puclic class RoleUtility 
{ 
    public Role getUserRoleByName(User user_, String roleName_) 
    { 
    User retRole = null; 
    Iterator<Role> i = roles_.iterator(); 
    while ((retRole == null) && i.hasNext()) 
    { 
     Role role = (Role) i.next(); 
     if (roleName_.isEqual(role.getName)) 
     retRole = role; 
    } 
    return retRole; 
    } 
} 

客户端代码,以检查的作用:

User user = ... 
Role role = RoleUtility.getRoleByName(user.getRoles(), roleName); 

留在你用这个解决方案的例子,你可以添加审查员/调解员的意见或类似的东西,没有任何数据结构的变化。

相关问题