Search code examples
javasql-serverjpaeclipselinkmany-to-one

Add a foreign key to composite primary key and changes in JPA Entity class


I have a class User with primary key (id) which corresponds to 'user' table in SQL Server database. My User class has a many to one relationship with Project Entity.

  public class User{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;

    @JoinColumn(name = "project", referencedColumnName = "id_project")
    @ManyToOne(optional = false)
    private Project project;
    }

database:

CREATE TABLE [dbo].[user](
    [id] [int] IDENTITY(27,1) NOT NULL,
    [name] [varchar](45) NULL,
    [project] [int] NOT NULL,
 CONSTRAINT [PK_user_1] PRIMARY KEY CLUSTERED 
(
 [id] ASC)

Now in my database I need to have two rows with same user ids but different projects so I changed my primary key to a composite primary key in my user table.

   user table:        id  name  id_project
                    ---------------------------
                       1   John      5
                       1   John      6

   project table:     id    name  
                    ---------------
                       5   Project5     
                       6   Project6

and changed my table like this

  CREATE TABLE [dbo].[user](
        [id] [int] IDENTITY(27,1) NOT NULL,
        [name] [varchar](45) NULL,
        [project] [int] NOT NULL,
     CONSTRAINT [PK_user_1] PRIMARY KEY CLUSTERED 
    (
    [id] ASC,
    [project_mode] ASC)

My question is that: Was this step required in my table? and if it was, then how can I change the @id of my User class?


Solution

  • JPA 2.1 allows derived IDs, allowing you to mark relationships as being part of the ID. User would look like this:

    @Entity
    @IdClass(UserPK.class)
    public class User{
        @Id
        @Basic(optional = false)
        @Column(name = "id")
        private Integer id;
    
        @Id
        @JoinColumn(name = "project", referencedColumnName = "id_project")
        @ManyToOne(optional = false)
        private Project project;
    }
    
    public class UserPK{
        private Integer id;
        private Integer project;//use the same type as the Project's ID.
    }