issue in implementing @IdClass

643 Views Asked by At

I am using jpa and hibernate as a jpa provider.

after learning the composite primary key concept in jpa, I am trying to implement the same using @IdClass annotation.

I have created a Project.java , in this I want to use deptId and projectId as my composite key.

so according to the referred concepts on internet, i have kept deptId and projectId into a ProjectID.class

please have a look at below ProjectID.java

public class ProjectID implements Serializable {

    private String deptId;
    private String projectId;

    public ProjectID()
    {

    }

    @Override
    public int hashCode()
    {
        int result=1;
        int prime=31;
        result = prime*result + ((deptId==null) ? 0 : deptId.hashCode());

        result = result +  (prime*result + ((projectId==null) ? 0 : projectId.hashCode()));

        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if(this==obj)
            return true;
        if(obj==null) return false;

        if(this.getClass() != obj.getClass())
            return false;
        ProjectID pId = (ProjectID)obj;
        if(deptId==null)
            if(pId.deptId!=null)
                return false;

        if(projectId==null)
            if(pId.projectId!=null)
                return false;

        return true;

    }

    public String getDeptId() {
        return deptId;
    }

    public void setDeptId(String deptId) {
        this.deptId = deptId;
    }

    public String getProjectId() {
        return projectId;
    }

    public void setProjectId(String projectId) {
        this.projectId = projectId;
    }

}

as you could see, I have implemented Serializable interface, equals and hashcode methods.

now have a look at Project.java

@Entity
@IdClass(entity.beans.ProjectID.class)
public class Project {

    @Id
    private String deptId;

    @Id
    private String projectId;

    private String name;

    public ProjectID getPid() {
        return pid;
    }

    public void setPid(ProjectID pid) {
        this.pid = pid;
    }

    private String manager;

    private ProjectID pid;

    private int headCount;

    public String getName() {
        return name;
    }

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

    public String getManager() {
        return manager;
    }

    public void setManager(String manager) {
        this.manager = manager;
    }

    public int getHeadCount() {
        return headCount;
    }

    public void setHeadCount(int headCount) {
        this.headCount = headCount;
    }
}

now this is the piece, I am not sure about. please tell me if this is right.

i am using following class to persist the Project entity.

public class DemoProject {

    EntityManagerFactory emf;
    EntityManager manager; 
    String persistenceUnitName="chapter.three";

    DemoProject()
    {
        emf = Persistence.createEntityManagerFactory(persistenceUnitName);
        manager = emf.createEntityManager();
    }

    public void runTheShow()
    {
        manager.getTransaction().begin();
        ProjectID id = new ProjectID();
        id.setDeptId("QA");
        id.setProjectId("Auto");

        Project p1 = new Project();
        p1.setName("World Bank");
        p1.setHeadCount(26);
        p1.setManager("Mr.Ashish");
        p1.setPid(id);
        manager.persist(p1);
        manager.getTransaction().commit();
        manager.close();
        emf.close();
    }

    public static void main(String args[])
    {
        DemoProject ob = new DemoProject();
        ob.runTheShow();
    }

}

on executing above code, I am unable to initialize the fields marked by @Id annotations. i am getting error as "ORA-01400: cannot insert NULL into ("SYSTEM"."PROJECT"."DEPTID")"

i need help in properly configuring composite keys via jpa annotations.

regards, ashish

1

There are 1 best solutions below

0
Ashish Parab On

first mistake was, i used instance of ProjectId class to initialize deptId and projectId. i modified the Project.java to add getter and setter for deptId and projectId.

and second mistake was i used pid attribute which is an instance of ProjectId class in entity. I removed this attribute.

it worked properly ! thanks