Hibernate一对多注释映射

时间:2015-06-05 13:08:42

标签: java hibernate

嗨,我有两张桌子如下。

1)任务 - id,name 2)资源 - id,name,defaultTask(Task.id的外键)

映射是一对多 - 一个任务可以有很多资源。

Task的代码如下所示。

@Entity
public class Resource implements Serializable {
private Long m_id;
private String m_name;
@Id
@GeneratedValue(
    strategy = GenerationType.AUTO
)
public Long getId() {
    return this.m_id;
}

public void setId(Long id) {
    this.m_id = id;
}

public String getName() {
    return this.m_name;
}

public void setName(String name) {
    this.m_name = name;
}
Task m_task;
@ManyToOne
@JoinColumn(
    name = "defaultTask"
)
public Task getTask() {
    return this.m_task;
}

public void setTask(Task task) {
    this.m_task = task;
}

Resource类的代码如下所示。

CREATE TABLE dbo.PEOPLE (
name VARCHAR(25) NOT NULL
, emailaddress VARCHAR(255) NOT NULL
, CONSTRAINT PEOPLE_ck_validemailaddress CHECK ( dbo.RegExValidate( emailaddress, N'^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$' ) = 1 )
) 

}

当我执行它时,我收到类似

的错误

初始SessionFactory创建failed.org.hibernate.MappingException:无法确定类型:java.util.List,对于列:[org.hibernate.mapping.Column(relatedResources)]

我做错了什么?我该如何解决这个问题?

4 个答案:

答案 0 :(得分:4)

您无法随机将注释应用于方法或字段。通常,您应该以与@Id相同的方式应用注释。

在Task类中,OneToMany应该像

@OneToMany
@JoinColumn(
    name = "defaultTask"
)
public List<Resource> getrelatedResources() {
    return m_relatedResources;
}

字段访问策略(由@Id注释确定)。将任何与JPA相关的注释放在每个方法的正上方而不是字段/属性,就像你的id在方法之上一样,它会让你远离形式例外。
此外,@ PredragMaric遇到的双向映射似乎也存在问题,因此您需要使用MappedBy来表示hibernate,该关系的关键在另一侧。点击Mapped by上的一个非常好的问题。

答案 1 :(得分:3)

您在同一个实体中混合注释字段和getter,您应该将@OneToMany移动到getter

@OneToMany
@JoinColumn(mappedBy = "task")
public List<Resource> getrelatedResources() {
    return m_relatedResources;
}

是的,正如其他人所提到的那样,它应该是mappedBy = "task"。我会赞成这种团队合作:)

答案 2 :(得分:3)

这里有很多错误:

  1. 你有时会注释字段,有时候会吸引人。注释的一半将被忽略:您必须保持一致。这是一个或另一个。
  2. 您不尊重Java Bean命名约定。获取者必须是getRelatedResources(),而不是getrelatedResources()
  3. 双向关联必须具有所有者方和反方。在OneToMany中,One始终是反面的。因此映射应为:
  4. @ManyToOne
    @JoinColumn(name = "defaultTask")
    public Task getTask() {
        return this.m_task;
    }
    

    @OneToMany(mappedBy = "task")
    public List<Resource> getRelatedResources() {
        return m_relatedResources;
    }
    

    我还强烈建议您尊重Java命名约定。变量应命名为idname,而不是m_idm_name。如果您选择注释字段,这一点尤为重要。

答案 3 :(得分:2)

@JoinColumn仅用于关系的所有者ToOne方面,在您的情况下为Resource#task。另一方面,您应该使用mappedBy属性来指定双向关系。将您的Task#relatedResources映射更改为此

@OneToMany(mappedBy = "task")
private List<Resource> m_relatedResources;

另外,正如@Viraj Nalawade注意到的那样(显然还有其他人),映射注释应该在字段属性上,而@Id优先使用。将@Id移至字段,或将@OneToMany移至getter。