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:
- User
- 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.