Search code examples
javajpapersistenceeclipselinkauto-generate

Auto-generate person_id and student_id for SINGLE_TABLE inheritance model


I have two entities person and Student, the student entity extends person and has its own identifier studentNumber. When creating a new student, i want to auto-generate both identification numbers.

The following snippet fails with: person_id being NULL

@RooEntity(identifierColumn = "personID", inheritanceType = "SINGLE_TABLE")
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING, length = 20)
@DiscriminatorValue("P")
public class Person {
}

The student Entity

@RooEntity
@DiscriminatorValue("S")
public class Student extends Person {


    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "studentNumber") 
    private long studentNumber;
}

Here is where i create a new student and the student number is generated but personid is not?

    private Student student;

    /**
     * @method Create a new student using our persistence model---Not Null variables
     */

    public void CreateNewStudent(String firstName, String lastName, String telephone, Date birthday, GenderType gender){


        student = new Student();
        //set our variables and persist
        student.setFirstName(firstName);
        student.setLastName(lastName);
        student.setTelephone(telephone);
        student.setBirthDay(birthday);
        student.setGender(gender);

        student.persist();
    }
}

is there any way i can create both studentNumber and personID when a student is created?


Solution

  • Based on your follow-up comments what you want is to have a primary key identifier for Person, and a unique identifier for Student. Note that with your current setup, only one of the keys can be auto generated (many DBMSes only allow one column per table to be auto incremented). So I would recommend that you first define your primary key column for Person:

    @Entity
    @Table(name="person")
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING,length=20)
    @DiscriminatorValue("P")
    public class Person {
        @Basic
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name="personId")
        private Long id;
    }
    

    Note that in your DB you will want to have the personId column as the auto-increment. Then define a separate generated value annotation for your student numbers. The example I show below uses a table generator but you can do whatever you want:

    @Entity
    @DiscriminatorValue("S")
    public class Student extends Person {
       @Basic
       @TableGenerator(name="ID_GEN", table="identifier_table", pkColumnName="seq_name",
            valueColumnName="seq_count", pkColumnValue="student_seq")
       @GeneratedValue(strategy = GenerationType.TABLE, generator = "ID_GEN")
       @Column(name = "studentNumber")
       private Long studentNumber;
    }
    

    Heres the DDL for the table you will need to support sequence number generation for Students, given the example above:

    create table identifier_table (
      id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      seq_name VARCHAR(255) NOT NULL,
      seq_count INT NOT NULL DEFAULT 0
    );
    

    And you would initially populate it with:

    insert into identifier_table (seq_name, seq_count) VALUES ('student_seq', 0);
    

    Of course, the simpler solution would be to declare your student identifier's as String, then you could just do the following, much easier setup:

    public class Student extends Person {
        @Basic
        @NotNull
        @Column(name = "studentId")
        private String studentIdentifier;
    }
    

    And before saving each record, set the student ID with the UUID class:

    aStudent.setStudentIdentifier(UUID.randomUUID().toString());
    

    Hope this helps.