Home > Blockchain >  Spring boot JPA BaseEntity with unique id to each class
Spring boot JPA BaseEntity with unique id to each class

Time:11-13

I have an abstract class BaseEntity which contains fields I want to share with multiple objects inside my project.

    @MappedSuperclass
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    public abstract class BaseEntity {
    
        @Id
        @Column(name = "objectId", insertable = false, updatable = false)
        @GeneratedValue(strategy = GenerationType.AUTO)
        private long objectId;
    
        @Column(name = "createdDate", updatable = false/*, columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP"*/)
        @CreationTimestamp
        private Date createdDate;
    
        @Column(name = "updatedDate"/*, columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP"*/)
        @UpdateTimestamp
        private Date updatedDate;
    
        @Column(name = "active", columnDefinition = "boolean default false")
        private boolean active;
}

I've multiple entities that are inherited from this class

For my example let's take two of them:

  1. User
  2. Contact

While saving a User object on the DB I can see the objectId field is getting incremented, but as well for another object such as Contact

For example:

I created an instance of User and saved it on DB, After persisting I can see my User.objectId = 1.

After that I created an instance of Contact and saved it on DB, After persisting I can see my Contact.objectId = 2

How can I make the field objectId increment separately for each Entity?

Thanks.

CodePudding user response:

You don't say whether you're using Hibernate as the JPA implementation, but since that's by far the most common choice, I'll answer based on it.

When you specify GenerationType.AUTO as the strategy for an @GeneratedValue identifier, the persistence provider (Hibernate) is left to choose the strategy. Hibernate uses SEQUENCE as its default choice* (unless you configure it otherwise), and that default behavior of SEQUENCE is to use a single, shared, DB sequence for all Hibernate-managed entities. That's why you're seeing the IDs increment across all entities/tables instead of each table's IDs be independent.

If you want to continue using sequence-based ID generation, it's possible to specify a sequence name for each entity, example here. That way, each entity type (table) can have an independent sequence of IDs. Note that if you have lots of entities/tables, this approach will produce a separate DB sequence for each one, which might not be ideal.

Another straightforward way to get what you're looking for would be to change the GenerationType to IDENTITY.

PLEASE NOTE: there are other options and lots of considerations (such as performance and support for batch inserts) when deciding on the ID generation strategy. I strongly urge you to read the Hibernate documentation, starting here, to fully understand the options and make an informed choice for your specific situation.


*This is not exactly true for MySQL since MySQL doesn't seem to natively support sequences. For MySQL, Hibernate will fall back to using the TABLE strategy, as described here.

CodePudding user response:

If you want a different sequence for each concrete class, the @Id and @GeneratedValue annotations - and thus the PK field - should be in the concrete class not in the root abstract one.

  • Related