How can I customize the sequence generator for each descendant when the generation strategy is defined on the ancestor?
I get an InvalidDataAccessResourceUsageException
when JPA tries to get the next id before inserting a new record.
If I create a sequence in the database with the name of the table and the default increment of 50, I do not get any errors. This is not an acceptable solution to the DBA team b/c it does not meet the naming standards.
The default generator working leads me to believe that the @SequenceGenerator
on the child is not being recognized. I tried various combinations of @Access(AccessType.FIELD)
and @Access(AccessType.PROPERTY)
on both parent and child but none recognized my custom SequenceGenerator attributes.
The DBA team wants me to "just" copy/paste the common attributes and code to every descendant. Certainly not DRY!
Any suggestions on how to get this to work?
Using Spring Boot 3.4.4
console log
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet [ERROR: relation "descendant_one_id_seq" does not exist
Position: 16] [select nextval('descendant_one_id_seq')]; SQL [select nextval('descendant_one_id_seq')]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:277)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:241)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:560)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:343)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:160)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165)
Ancestor
@MappedSuperclass
public abstract class AbstractDatabaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity_generator")
protected Long id;
// other common attributes
// common methods to all descendants
}
Descendant
@Entity
@Table(name = "descendant_one")
public class DescendantOne extends AbstractDatabaseEntity {
@SequenceGenerator(name = "entity_generator", sequenceName = "descendant_one_id_seq", allocationSize = 1)
public Long getId() {
return id;
}
}
Descendant
@Entity
@Table(name = "descendant_two")
public class DescendantTwo extends AbstractDatabaseEntity {
@SequenceGenerator(name = "entity_generator", sequenceName = "descendant_two_id_seq", allocationSize = 1)
public Long getId() {
return id;
}
}