“使用JPA和Spring引导在实体中引用实体的映射中的重复列”

时间:2017-12-27 18:42:28

标签: spring hibernate jpa

我正在尝试运行我的春季启动,ibatis,jpa应用程序。

这是我在H2数据库中运行的sql脚本。

CREATE TABLE COMMITTEE(
    CODE NUMBER PRIMARY KEY,
    NAME VARCHAR2(100),
    P_CODE NUMBER,
    CONSTRAINT P_CODE_FK FOREIGN KEY (P_CODE) REFERENCES COMMITTEE(CODE) 
);

Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(1, 'Parent 1', NULL);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(2, 'Parent 2', NULL);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(3, 'Parent 3', NULL);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(4, 'Child 1.1', 1);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(5, 'Child 1.2', 1);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(6, 'Child 1.3', 1);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(7, 'Child 3.1', 3);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(8, 'Child 3.2', 3);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(9, 'Child 3.3', 3);
Insert into COMMITTEE(CODE, NAME, P_CODE) VALUES(10, 'Child 3.1.1', 7);

这是我的实体:

package org.gso.committee.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "committee")
public class Committee implements Serializable {

    private static final long serialVersionUID = 18787545L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long code;
    private String name;
    @Column(nullable = true)
    private long p_code;

    @ManyToOne()
    @JoinColumn(name = "p_code")
    private Committee parent;

    @OneToMany(mappedBy = "parent")
    private List<Committee> children = new ArrayList<>(0);

    public Committee() {
    }

    public Committee(long code, String name, long p_code) {
        this.code = code;
        this.name = name;
        this.p_code = p_code;
    }

    public long getCode() {
        return code;
    }

    public void setCode(long code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getP_code() {
        return p_code;
    }

    public void setP_code(long p_code) {
        this.p_code = p_code;
    }

    public Committee getParent() {
        return parent;
    }

    public void setParent(Committee parent) {
        this.parent = parent;
    }

    public List<Committee> getChildren() {
        return children;
    }

    public void setChildren(List<Committee> children) {
        this.children = children;
    }

    @Override
    public String toString() {
        return "Committee [code=" + code + ", name=" + name + ", p_code=" + p_code + "]";
    }
}

问题在于,当我总是得到错误时:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: org.gso.committee.model.Committee column: p_code (should be mapped with insert="false" update="false")

1 个答案:

答案 0 :(得分:1)

问题是为什么将p_code映射为单独的属性,因为它已经通过引用父映射进行了映射。

但是如果你想要这个属性,你必须将它声明为只读

@Column(nullable = true, insertable = false, updateable = false)
private long p_code;

设置父引用很重要。最好的方法是添加一些方便的方法:

public void addChild(Committee committee) {
   committee.setParent(this);
   children.add(committee);
}

public void removeChild(Committee committee) {
   committee.setParent(null);
   children.remove(committee);
}