简体   繁体   中英

Foreign key as primary key on Hibernate/JPA2.0

I'm unable to create a jpa model of my database model, and I'm having problems with the primary and foreign keys. I'm using PersistenceContextType.TRANSACTION , and when I persist the foo object and its state i'm getting the folowing error:

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

I'm using the eclipse JPA plugin to create my entities, and until now, it has been working well. The server is a JBoss 6.1.0 (JPA2.0 and Hibernate 3.6.6)

I'm going to try to give you all information.

Those are the entities:

Foo entity and its PK. (I've marked ID_STATE as insertable=false, updatable=false because at the server start I'm getting an exception saying that i've to mark it as 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;
    }
}

The Foo States entity and its primary key object

@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;
    }
}

The tables script's are:

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"))

I've found a partial solution. With this solution I can insert new data but I can't recover them.

I'm little bit lost :S

The partial solution was: At the 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;

And the 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;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM