1

I am using java and hibernate annotations to define the database schema and want to specify the foreign key in one table as the primary key.

I am getting an error when I set this up and think it could be down to how I am setting up the foreign key as the primary key because when I use a normal primary key I don't get an error.

What is the correct way to set up a foreign key as the primary key?

My current code set up is :

@Table(name="BATCH_STEP_EXECUTION_CONTEXT")
public class BatchStepExecutionContext implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JoinColumn(name = "STEP_EXECUTION_ID" , columnDefinition="BIGINT NOT NULL", referencedColumnName="STEP_EXECUTION_ID")
    @ForeignKey(name="STEP_EXEC_CTX_FK ")
    @IndexColumn(name="IDX_STEP_EXEC_CTX")  
    private BatchStepExecution batchStepExecution;

and is referenced by the Batch Step Execution table as:

// bi-directional many-to-one association to Batch Step Execution Context
@OneToMany(mappedBy = "batchStepExecution", cascade = {CascadeType.ALL})
private List<BatchStepExecutionContext> batchStepExecutionContext; 

the error I'm getting when I try to run the code is:

Unable to read the mapped by attribute for batchStepExecutionContext in com.ccs.nbook.domain.model.BatchStepExecutionContext!

The tables I'm trying to model in the java code are:

CREATE TABLE BATCH_STEP_EXECUTION
    (
    STEP_EXECUTION_ID  BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (MAXVALUE 9223372036854775807),
    VERSION            BIGINT NOT NULL,
    STEP_NAME          VARCHAR (100) NOT NULL,
    JOB_EXECUTION_ID   BIGINT NOT NULL,
    STATUS             VARCHAR (10),
    COUNT              BIGINT,
    CONSTRAINT JOB_EXEC_STEP_FK FOREIGN KEY (JOB_EXECUTION_ID) REFERENCES BATCH_JOB_EXECUTION (JOB_EXECUTION_ID),
    PRIMARY KEY (STEP_EXECUTION_ID)
    )
    ;


CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT
    (
    STEP_EXECUTION_ID  BIGINT NOT NULL,
    SHORT_CONTEXT      VARCHAR (2500) NOT NULL,
    SERIALIZED_CONTEXT LONG VARCHAR,
    PRIMARY KEY (STEP_EXECUTION_ID),
    CONSTRAINT STEP_EXEC_CTX_FK FOREIGN KEY (STEP_EXECUTION_ID) REFERENCES BATCH_STEP_EXECUTION (STEP_EXECUTION_ID)
    )
    ;

So I am trying to model the relationship of STEP_EXECUTION_ID between both tables where it is a primary key in BATCH_STEP_EXECUTION and is a primary key and foreign key in BATCH_STEP_EXECUTION_CONTEXT

user3165854
  • 1,505
  • 8
  • 48
  • 100
  • Perhaps this link can be useful. http://stackoverflow.com/questions/16287007/hibernate-envers-unable-to-read-the-mapped-by-attribute – Developer Oct 15 '15 at 13:45

1 Answers1

0

Not pretty sure you mean with

want to specify the foreign key in one table as the primary key.

Don't get exactly what you mean... this foreign key is already primary key, right?


Anyway, to know what's going on (and not only in this case), read the Exception:

Caused by: org.hibernate.MappingException: Unable to read the mapped by attribute for batchJobExecutionContext in com.domain.model.BatchJobExecutionContext!

It says: There's a missing mappedby in BatchJobExecutionContext!

How to fix it?
Reading this answer with a simple example:

@Entity
public class Company {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
    private List<Branch> branches;
}

@Entity
public class Branch {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "companyId")
    private Company company;
}

I can see you are missing the @ManyToOne side of the relation @OneToMany and it's mappedby attribute. As long you used: @OneToMany(mappedBy = "batchStepExecution", cascade = {CascadeType.ALL}) you must add @ManyToOne anottation in the other side. So your code need to be like this:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "STEP_EXECUTION_ID" , columnDefinition="BIGINT NOT NULL", referencedColumnName="STEP_EXECUTION_ID")
@ForeignKey(name="STEP_EXEC_CTX_FK ")
@IndexColumn(name="IDX_STEP_EXEC_CTX")  
private BatchStepExecution batchStepExecution;

NOTES:

Community
  • 1
  • 1
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
  • Sorry, I've pasted the incorrect error message and corrected it above. I've updated the code to include the ManyToOne annotation which I missed but I'm getting the same error. If I separate the foreign key from the primary key and setup the primary key as an integer id then it works OK.. Its only when I try to setup the foreign key as the primary key I have the problem. – user3165854 Oct 15 '15 at 14:21
  • as I told you at first: **you cannot use nothing as foreign key if it is not primary key** that makes no sense.... so field **MUST** be primary key – Jordi Castilla Oct 15 '15 at 14:26
  • I might have misunderstood. The primary key from the BatchStepExecution table is a foreign key in the BatchStepExecutionContext table and I would like to set this to be the primary key in the BatchStepExecutionContext table as well. I've been looking at @PrimaryKeyJoinColumn but have also seen over approaches such as setting the primary key strategy to 'foreign' and want to know whether these were appropriate for what I'm trying to do – user3165854 Oct 15 '15 at 14:35
  • I've added 2 of the tables I'm trying to model with further explanation above which will hopefully help – user3165854 Oct 15 '15 at 14:44