外键是Hibernate / JPA2.0的主键

时间:2014-04-21 07:41:05

标签: java hibernate jpa foreign-keys composite-key

我无法创建我的数据库模型的jpa模型,而且我遇到了主键和外键的问题。我正在使用PersistenceContextType.TRANSACTION,当我持久保存foo对象及其状态时,我得到了以下错误:

WARN - SQL Error: 957, SQLState: 42000. ERROR - ORA-00957: duplicate column name.

我正在使用eclipse JPA插件来创建我的实体,直到现在,它一直运行良好。服务器是JBoss 6.1.0(JPA2.0和Hibernate 3.6.6)

我将尝试向您提供所有信息。

这些是实体:

Foo实体及其PK。 (我已经标记了ID_STATE as insertable=false, updatable=false,因为在服务器启动时我得到一个例外,说我要将其标记为insert="flase" and update="false"

@Entity
@NamedQuery(name = "Foo.findAll", query = "SELECT p FROM Foo p")
public class Foo implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private FooPK id;

    public Foo() {
    }

    public FooPK getId() {
        return this.id;
    }

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

}

@Embeddable
public class FooPK implements Serializable {

    private static final long serialVersionUID = 1L;

    private long num1;

    private long num2;

    private long num3;

    private long num4;

    private long num5;

    public FooPK() {
    }
    public long getNum1() {
        return this.num1;
    }
    public void setNum1(long num1) {
        this.num1 = num1;
    }
    public long getNum2() {
        return this.num2;
    }
    public void setNum2(long num2) {
        this.num2 = num2;
    }
    public long getNum3() {
        return this.num3;
    }
    public void setNum3(long num3) {
        this.num3 = num3;
    }
    public long getNum4() {
        return this.num4;
    }
    public void setNum4(long num4) {
        this.num4 = num4;
    }
    public long getNum5() {
        return this.num5;
    }
    public void setNum5(long num5) {
        this.num5 = num5;
    }
}

Foo States实体及其主要关键对象

@Entity
@Table(name="STATES_FOO")
@NamedQuery(name="StatesFoo.findAll", query="SELECT e FROM StatesFoo e")
public class StatesFoo implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private StatesFooPK id;

    //bi-directional many-to-one association to State
    @ManyToOne
    @JoinColumn(name="ID_STATE", insertable=false, updatable=false)
    private State state;


    //bi-directional many-to-one association to Foo
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="NUM1", referencedColumnName="NUM1"),
        @JoinColumn(name="NUM2", referencedColumnName="NUM2"),
        @JoinColumn(name="NUM3", referencedColumnName="NUM3"),
        @JoinColumn(name="NUM4", referencedColumnName="NUM4"),
        @JoinColumn(name="NUM5", referencedColumnName="NUM5")
        })
    private Foo foo;

    public StatesFoo() {
    }

    public StatesFooPK getId() {
        return this.id;
    }

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

    public Foo getFoo() {
        return this.Foo;
    }

    public void setFoo(Foo foo) {
        this.foo = foo;
    }

}

@Embeddable
public class StatesFooPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    @Column(name="ID_STATE", insertable=false, updatable=false)
    private String idState;

    @Column(name = "TIMESTAMP")
    private Timestamp timestamp;

    @Column(insertable=false, updatable=false)
    private long num1;

    @Column(insertable=false, updatable=false)
    private long num2;

    @Column(insertable=false, updatable=false)
    private long num3;

    @Column(insertable=false, updatable=false)
    private long num4;

    @Column(insertable=false, updatable=false)
    private long num5;

    public EstadosFooPK() {
    }
    public String getIdState() {
        return this.idState;
    }
    public void setIdState(String idState) {
        this.idState = idState;
    }

    public Timestamp getTimestamp() {
        return this.timestamp;
    }

    public void setTimestamp(Timestamp timestamp) {
        this.timestamp = timestamp;
    }

    public long getNum1() {
        return this.num1;
    }
    public void setNum1(long num1) {
        this.num1 = num1;
    }
    public long getNum2() {
        return this.num2;
    }
    public void setNum2(long num2) {
        this.num2 = num2;
    }
    public long getNum3() {
        return this.num3;
    }
    public void setNum3(long num3) {
        this.num3 = num3;
    }
    public long getNum4() {
        return this.num4;
    }
    public void setNum4(long num4) {
        this.num4 = num4;
    }
    public long getNum5() {
        return this.num5;
    }
    public void setNum5(long num5) {
        this.num5 = num5;
    }
}

表格脚本是:

CREATE TABLE "FOO" 
   (    "NUM1" NUMBER(2,0) NOT NULL ENABLE, 
    "NUM2" NUMBER(5,0) NOT NULL ENABLE, 
    "NUM3" NUMBER(4,0) NOT NULL ENABLE, 
    "NUM4" NUMBER(2,0) NOT NULL ENABLE, 
    "NUM5" NUMBER(2,0) NOT NULL ENABLE,
    CONSTRAINT "FOO_PK" PRIMARY KEY ("NUM1", "NUM2", "NUM3", "NUM4", "NUM5")}

 CREATE TABLE "STATES_FOO" 
   (    "NUM1" NUMBER(2,0) NOT NULL ENABLE, 
    "NUM2" NUMBER(5,0) NOT NULL ENABLE, 
    "NUM3" NUMBER(4,0) NOT NULL ENABLE, 
    "NUM4" NUMBER(2,0) NOT NULL ENABLE, 
    "NUM5" NUMBER(2,0) NOT NULL ENABLE,
    "ID_STATE" VARCHAR2(2 CHAR) NOT NULL ENABLE, 
    "TIMESTAMP" TIMESTAMP (6) NOT NULL ENABLE, 
     CONSTRAINT "STATES_FOO_PK" PRIMARY KEY ("ID_STATE", "TIMESTAMP", "NUM1", "NUM2", "NUM3", "NUM4", "NUM5"),
     CONSTRAINT "STATES_FOO_FOO_FK" FOREIGN KEY ("NUM1", "NUM2", "NUM3", "NUM4", "NUM5")
      REFERENCES "FOO" ("NUM1", "NUM2", "NUM3", "NUM4", "NUM5"),
     CONSTRAINT "STATES_FOO_STATE_FK" FOREIGN KEY ("ID_STATE")
      REFERENCES "STATE" ("ID_STATE"))

1 个答案:

答案 0 :(得分:0)

我找到了部分解决方案。使用此解决方案,我可以插入新数据,但我无法恢复它们。

我有点失落:S

部分解决方案是: 在StatesFoo:

@ManyToOne
    @MapsId(value="fooId")
    @JoinColumns(value = {
        @JoinColumn(name="num1", referencedColumnName="num1"),
        @JoinColumn(name="num2", referencedColumnName="num2"),
        @JoinColumn(name="num3", referencedColumnName="num3"),
        @JoinColumn(name="num4", referencedColumnName="num4"),
        @JoinColumn(name="num5", referencedColumnName="num5")
        })
    private Foo foo;

还有StatesFooPk:

@Embeddable
    public class StatesFooPK implements Serializable {
        //default serial version id, required for serializable classes.
        private static final long serialVersionUID = 1L;

        @Column(name="ID_STATE", insertable=false, updatable=false)
        private String idState;

        @Column(name = "TIMESTAMP")
        private Timestamp timestamp;

        @Embbebed
        private FooPK fooId;

        public EstadosFooPK() {
        }
        public String getIdState() {
            return this.idState;
        }
        public void setIdState(String idState) {
            this.idState = idState;
        }

        public Timestamp getTimestamp() {
            return this.timestamp;
        }

        public void setTimestamp(Timestamp timestamp) {
            this.timestamp = timestamp;
        }

        public long getFooId() {
            return this.fooId;
        }
        public void setFooId(long fooId) {
            this.fooId= fooId;
        }
    }