cancel
Showing results for 
Search instead for 
Did you mean: 

ejb relationship mapping in Entity with compound primary key.

Former Member
0 Kudos

Hi All ,

i am working with EJB 3.0 on Netweaver 7.1 sp 5. I am having two entity classes ErecJobID and ErecJobAddFeild. i want to map relationship as one-many between ErecJobID and ErecJobAddFeild , i.e for one JobID from ErecJobID can have one/many records in ErecJobAddField. In ErecJobAddField key is composite of JobID and FieldID. I am not getting how to map relationship in case of composite keys. I am sending code of my two classes please help me in this issue.

@Entity

@Table(name="EREC_JOB_ADD_FIELD")

public class ErecJobAddField implements Serializable {

@EmbeddedId

private ErecJobAddField.PK pk;

@Column(name="FIELD_VALUE")

@Lob

private String fieldValue;

@Column(name="CR_DATE")

private Timestamp crDate;

@Column(name="CR_USER")

private String crUser;

@Column(name="FIELD_NAME")

private String fieldName;

@Column(name="MOD_USER")

private String modUser;

@Column(name="MOD_DATE")

private Timestamp modDate;

private static final long serialVersionUID = 1L;

public ErecJobAddField() {

super();

}

public ErecJobAddField.PK getPk() {

return this.pk;

}

public void setPk(ErecJobAddField.PK pk) {

this.pk = pk;

}

public String getFieldValue() {

return this.fieldValue;

}

public void setFieldValue(String fieldValue) {

this.fieldValue = fieldValue;

}

public Timestamp getCrDate() {

return this.crDate;

}

public void setCrDate(Timestamp crDate) {

this.crDate = crDate;

}

public String getCrUser() {

return this.crUser;

}

public void setCrUser(String crUser) {

this.crUser = crUser;

}

public String getFieldName() {

return this.fieldName;

}

public void setFieldName(String fieldName) {

this.fieldName = fieldName;

}

public String getModUser() {

return this.modUser;

}

public void setModUser(String modUser) {

this.modUser = modUser;

}

public Timestamp getModDate() {

return this.modDate;

}

public void setModDate(Timestamp modDate) {

this.modDate = modDate;

}

@Embeddable

public static class PK implements Serializable {

@Column(name="JOB_ID")

private String jobId;

@Column(name="FIELD_ID")

private int fieldId;

private static final long serialVersionUID = 1L;

public PK() {

super();

}

public String getJobId() {

return this.jobId;

}

public void setJobId(String jobId) {

this.jobId = jobId;

}

public int getFieldId() {

return this.fieldId;

}

public void setFieldId(int fieldId) {

this.fieldId = fieldId;

}

@Override

public boolean equals(Object o) {

if (o == this) {

return true;

}

if ( ! (o instanceof PK)) {

return false;

}

PK other = (PK) o;

return this.jobId.equals(other.jobId)

&& (this.fieldId == other.fieldId);

}

@Override

public int hashCode() {

return this.jobId.hashCode()

^ this.fieldId;

}

}

}

@Entity

@Table(name="EREC_JOB")

public class ErecJob implements Serializable {

@Id

@Column(name="JOB_ID")

private String jobId;

@Column(name="REQUIREMENT")

private String requirement;

@Column(name="NOTE")

private String note;

@Lob

@Column(name="RESPONSIBILITIES")

private String responsibilities;

@Column(name="EDU_QUALIFICATION")

private String eduQualification;

@Column(name="JOB_DESCRIPTION")

@Lob

private String jobDescription;

@Column(name="AGE")

private String age;

@Column(name="WORK_EXPERIENCE")

private String workExperience;

@Column(name="JOB_NAME")

private String jobName;

@Column(name="CR_USER")

private String crUser;

@Column(name="MOD_DATE")

private Timestamp modDate;

@Column(name="ORG_ID")

private String orgId;

@Column(name="CR_DATE")

private Timestamp crDate;

@Column(name="MOD_USER")

private String modUser;

//@OneToMany(targetEntity=com.apl.entity.jobadditionalfields.ErecJobAddField.class, mappedBy = "pk")

//Collection<ErecJobAddField> erecJobAddFields;

private static final long serialVersionUID = 1L;

public ErecJob() {

super();

}

public String getJobId() {

return this.jobId;

}

public void setJobId(String jobId) {

this.jobId = jobId;

}

public String getRequirement() {

return this.requirement;

}

public void setRequirement(String requirement) {

this.requirement = requirement;

}

public String getNote() {

return this.note;

}

public void setNote(String note) {

this.note = note;

}

public String getResponsibilities() {

return this.responsibilities;

}

public void setResponsibilities(String responsibilities) {

this.responsibilities = responsibilities;

}

public String getEduQualification() {

return this.eduQualification;

}

public void setEduQualification(String eduQualification) {

this.eduQualification = eduQualification;

}

public String getJobDescription() {

return this.jobDescription;

}

public void setJobDescription(String jobDescription) {

this.jobDescription = jobDescription;

}

public String getAge() {

return this.age;

}

public void setAge(String age) {

this.age = age;

}

public String getWorkExperience() {

return this.workExperience;

}

public void setWorkExperience(String workExperience) {

this.workExperience = workExperience;

}

public String getJobName() {

return this.jobName;

}

public void setJobName(String jobName) {

this.jobName = jobName;

}

public String getCrUser() {

return this.crUser;

}

public void setCrUser(String crUser) {

this.crUser = crUser;

}

public Timestamp getModDate() {

return this.modDate;

}

public void setModDate(Timestamp modDate) {

this.modDate = modDate;

}

public String getOrgId() {

return this.orgId;

}

public void setOrgId(String orgId) {

this.orgId = orgId;

}

public Timestamp getCrDate() {

return this.crDate;

}

public void setCrDate(Timestamp crDate) {

this.crDate = crDate;

}

public String getModUser() {

return this.modUser;

}

public void setModUser(String modUser) {

this.modUser = modUser;

}

}

Accepted Solutions (1)

Accepted Solutions (1)

adrian_goerler
Active Participant
0 Kudos

Hi Kavita,

as far as I see, you are having a unidirectional 1:n relationship from ErecJob to ErecJobAddField. You've got to map this with a join table with one column referencing the PK of ErecJob and two columns referencing the two PK columns of ErecJobAddField .

On ErecJob:


@OneToMany
    @JoinTable(name = "JOB_JOIN_FIELD", 
        joinColumns = { @JoinColumn(name = "JOB_ID") }, // references PK of ErecJob
        inverseJoinColumns = { // two join columns to ErecJobAddField
            @JoinColumn(name = "ADD_JOB_ID", referencedColumnName = "JOB_ID"),
            @JoinColumn(name = "ADD_FIELD_ID", referencedColumnName = "FIELD_ID") })
Collection<ErecJobAddField> erecJobAddFields;

You could make this much simpler if you'd make the relationship bidirectional. Then, you could use a plain FK mapping

On ErecJobAddField:


@ManyToOne
@JoinColumn(name="JOB_ID", insertable=false; updatable=false)
ErecJob erecJob;

On ErecJob:


@OneToMany (mappedBy="erecJob")
Collection<ErecJobAddField> erecJobAddFields;

I hope this helps

-Adrian

Former Member
0 Kudos

Thnx for reply. what i cn get from ur reply is , if i m using compound key then i have to add Collection of ErecJobAddField in ErecJob , and on top of this field i hv to write this code

@OneToMany

@JoinTable(name = "JOB_JOIN_FIELD",

joinColumns = { @JoinColumn(name = "JOB_ID") }, // references PK of ErecJob

inverseJoinColumns = { // two join columns to ErecJobAddField

@JoinColumn(name = "ADD_JOB_ID", referencedColumnName = "JOB_ID"),

@JoinColumn(name = "ADD_FIELD_ID", referencedColumnName = "FIELD_ID") })

Collection<ErecJobAddField> erecJobAddFields; // Added Field

The above code is for unidirectional relationship. Correct me if i m wrong.

But i m not getting bidirectional relationship code

@ManyToOne

@JoinColumn(name="JOB_ID", insertable=false; updatable=false)

ErecJob erecJob;

On ErecJob:

@OneToMany (mappedBy="erecJob")

Collection<ErecJobAddField> erecJobAddFields;

u have written as

On ErecJobAddField:

@ManyToOne

@JoinColumn(name="JOB_ID", insertable=false; updatable=false)

ErecJob erecJob;

but in ErecJobAddField i have compound key , so where should i add above code??? above JobID field in PK class????

adrian_goerler
Active Participant
0 Kudos

Hi Kavita

ErecJob as a simple id , ErecJobAddField has a compound id.

You are having two options:

1) You are having a unidirectional 1:n from ErecJob to ErecJobAddField. In this case, you need a join table with three columns (one column "JOB_ID"referring to the PK column of ErecJob "JOB_ID", two columns "ADD_JOB_ID" an "ADD_FIELD_ID" referring to the two PK columns of ErecJobAddField ("JOB_ID" and "FIELD_ID")) as described above.

2) Alternatively, you may make the relationship bidirectional. In this case you are using the simple Fk mapping. The database table ErecJobAddField is mapped to holds the FK to the PK of the table ErecJob is mapped to ("JOB_ID"). But this FK is just the first component "JOB_ID" of the compound key of ErecjobAddField. Therefore, you don't need any additional database column.

So on the relationship field referring from ErecJobAddField to ErecJob, you need this annotation:

@ManyToOne
@JoinColumn(name="JOB_ID", insertable=false, updatable=false)
ErecJob erecJob;

insertable = false, updatable=false indicates that the column "JOB_ID" is also part of the compound PK.

On the other (non-owning side) ErecJob, you just need a "mappedBy":

@OneToMany (mappedBy="erecJob")
Collection<ErecJobAddField> erecJobAddFields;

I hope this is clearer now.

-Adrian

Former Member
0 Kudos

Thnx.

Former Member
0 Kudos

Than for reply. i hv tried ur code n its working fine. could u help me in one to one mapping??? i am having two entoties ErecJob and ErecOrgTree , Every job in from ErecJob had exactly one orgtree from ErecOrgTree . And Every orgTree in ErecOrgTree can have 1 to many Jobs fron ErecJob. Iwant to map relationship between ordTree and job , as JobHasManyOneOrgTree and OrgTreeHadOneOrMoreJobs. m sending u my entities n code which i wrote for mapping but its not working. I just deleted String orgId from ErecJob and Added field variable ErecOrgId erecOrgId. n did mappimg but its not working.

public class ErecOrgTree implements Serializable {

@Id

@Column(name="ORG_ID")

private String orgId; // Primary key in table

/* Other field variables from table */

private static final long serialVersionUID = 1L;

@OneToMany(mappedBy = "erecOrgTree")

private Collection<ErecJob> ereCollection = new ArrayList<ErecJob>();

public ErecJob getErecJob() {

return erecJob;

}

public void setErecJob(ErecJob erecJob) {

this.erecJob = erecJob;

}

/* Getter Setter Methods of other field variables */

}

public class ErecJob implements Serializable {

@Id

@Column(name="JOB_ID", table = "EREC_JOB")

private String jobId;

/* Other field variables */

//@Column(name="ORG_ID") // Deleted ordId and added new one as ErecOrgTree orgId

// private String orgId ;

@OneToOne(fetch=LAZY, optional = false, mappedBy = "orgId", targetEntity = com.apl.entity.orgtree.ErecOrgTree.class)

private ErecOrgTree orgId;

private static final long serialVersionUID = 1L;

public ErecOrgTree getOrgId() { // Getter Setter for other field variables

return orgId;

}

public void setOrgId(ErecOrgTree orgId) {

this.orgId = orgId;

}

/* public String getOrgId() {

return this.orgId;

}

public void setOrgId(String orgId) {

this.orgId = orgId;

} */ // commenteted getter setter methods for String orgId field

public ErecOrgTree getErecOrgTree() {

return erecOrgTree;

}

public void setErecOrgTree(ErecOrgTree erecOrgTree) {

this.erecOrgTree = erecOrgTree;

}

}

but i am getting error as "Owning relationship with name orgId not found among relationships of the target class com.apl.entity.orgtree.ErecOrgTree." . Please let me know where i went wrong in mapping relationship????

adrian_goerler
Active Participant
0 Kudos

Hi Kavita,

you are having a bidirectional n:1 relationship between ErecJob and ErecOrgTree. You map this using a FK mapping. The owing side is the side holding the FK that is ErecJob. Whats wrong with your mapping is that you are having "mappedBy" on both sides.

You map this as follows:

On ErecJob:

@OneToOne(fetch=LAZY, optional = false) // this is the owining side -> no mappedMy
private ErecOrgTree orgId;

On ErecOrgTree:

@OneToMany(mappedBy = "erecOrgTree")
private Collection<ErecJob> ereCollection = new ArrayList<ErecJob>();

I hope this helps,

Adrian

Former Member
0 Kudos

Thnx a lot. currently i mapped it as ErecOrgTree => ErecJob as oneto many and , ErecJob =>ErecOrgTree as many to one. is it ok???

adrian_goerler
Active Participant
0 Kudos

Hi,

sure thats what its got to be like.

-Adrian

Answers (0)