Wednesday, October 23, 2013

Primary key generation strategies in JPA(Java Persistence API)

Hi,

In this post we will discuss about generating primary key values in JPA(Java Persistence API).In general there are two strategies.A sequence number in JPA is a sequential id generated by the JPA implementation and automatically assigned to new objects

Natural id :- is like using telephone number,SSN number etc as primary keys in tables
Generated id :- where primary key value is generated by application/framework

Generated id is preferably used because data of Natural Id may change with time
There are different ways of generating primary key id's in JPA
  • Identity
  • Table
  • Sequence
  • Auto
Each one of it is described below with examples
  • IDENTITY :-Specifies the use of database identity column.@GeneratedValue annotation indicates that identifier value should be automatically created, and the specified strategy of IDENTITY indicates that an identity column should be used to generate the identifier

        @Entity
        public class Company implements Serializable {
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private BigDecimal sno;

  • TABLE :- There are two ways of generating sequence using TABLE

    • Using default strategy:-JPA will create a default table for identifier generation,Specify the strategy of TABLE in the @GeneratedValue. JPA will create default table during schema generation at run time
      @Entity
         public class Company implements Serializable {
         private static final long serialVersionUID = 1L;
         @Id
         @GeneratedValue(strategy = GenerationType.TABLE)
         private BigDecimal sno;

    • User defined table :- We can map an existing table or tell JPA to create a table with user defined name columns etc. Generating or specifying a table will be done by using @TableGenerator annotation,after declaring the required details then we can use @GeneratedValue

      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @TableGenerator(name = "javarecent_seq", table = "GEN_ID", pkColumnName = "NAME_ID", valueColumnName = "VAL_ID", pkColumnValue = "GEN_INV")
      private BigDecimal sno;
 
NAME_ID
    VAL_ID
    GEN_INV
    <Recent_Generated_Value>
      When ever a new value is required,value from VAL_ID will be picked and incremented and send that value to JPA to use.we can specify the allocationSize = "value to be incremented"

  • Sequence generator :- will create a sequence for generating unique values.Like TABLE generator JPA provides two ways
    • Default Sequence :- JPA can generate unique values for a persistence object.JPA will generate/create a default sequence object during run time and will be used for genearting unique values
      @Entity
      public class Company implements Serializable {
      private static final long serialVersionUID = 1L;
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE)
      private BigDecimal sno;
    • User defined sequence:- If we want to use specific sequence already created or to create and use a new one can be possible by using @SequenceGenerator annotation
      @Entity
      public class Company implements Serializable {
      private static final long serialVersionUID = 1L;
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE,generator="my_seq")
      @SequenceGenerator(name = "my_seq" , sequenceName="pk_generator", allocationSize=3)
      private BigDecimal sno;
In above example a example a sequence is generated if not present with name pk_generator and each time a new value will be created with an increment of 3 as specified in allocationSize ,this sequence is named as my_seq and used in @GeneratedValue

  • AUTO :- Indicates that JPA will pick the appropriate generation strategy for a particular database,there is no gaurentee that generated values will be in sequence,by default TABLE strategy is picked as this is the mosdt portable approach which is supported by all databases
        @Entity
        public class Company implements Serializable {
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private BigDecimal sno;

    Common Problems
    Error when allocating a sequence number.
  1. Errors such as "table not found","invalid column" can occur if you do not have a SEQUENCE table defined in your database, or its schema does not match what you have configured, or what your JPA provider is expecting by default. Ensure you create the sequence table correctly, or configure your @TableGenerator to match the table that you created, or let your JPA provider create you tables for you (most JPA provider support schema creation). You may also get an error such as "sequence not found", this means you did not create a row in the table for your sequence. You must insert an initial row in the sequence table for your sequence with the initial id (i.e. INSERT INTO SEQUENCE_TABLE (SEQ_NAME, SEQ_COUNT) VALUES ("EMP_SEQ", 0)), or let your JPA provider create your schema for you.
  2. If there is any issue using TABLE sequence creation in JPA.We need to first change/check the persistence.xml file
    Specify <property name="eclipselink.ddl-generation" value="create-tables"/>



                         Happy Learning

Please provide your valuable comments on this article and share it across your network.


Contact me @ sudheer.reddy@live.com or admin@java-recent.com

No comments:

Post a Comment

Like and Share