Как настроить генератор последовательностей JPA в Entity с предком @MappedSuperclassJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как настроить генератор последовательностей JPA в Entity с предком @MappedSuperclass

Сообщение Anonymous »

Как настроить генератор последовательностей для каждого потомка, если стратегия генерации определена для предка?
Я получаю исключение InvalidDataAccessResourceUsageException, когда JPA пытается получить следующий идентификатор перед вставкой новой записи.
Если я создаю в базе данных последовательность с именем таблицы и шагом по умолчанию 50, я не получаю никаких ошибок. Это неприемлемое решение для команды администраторов баз данных, поскольку оно не соответствует стандартам именования.
Работа генератора по умолчанию заставляет меня полагать, что @SequenceGenerator на дочернем элементе не распознается. Я пробовал различные комбинации @Access(AccessType.FIELD) и @Access(AccessType.PROPERTY) как для родительского, так и для дочернего элемента, но ни один из них не распознал мои пользовательские атрибуты SequenceGenerator.
Команда администраторов базы данных хочет, чтобы я «просто» скопировал/вставил общие атрибуты и код каждому потомку. Конечно, не СУХОЙ!
Обновление
Я пробовал различные комбинации аргумента генератора для абстрактного базового класса и аргумента имени для класса-потомка; только предок, только потомок, совпадающая строка, несовпадающая строка. По-прежнему возникают ошибки.
В этом ответе на другой вопрос говорится, что это можно сделать, но в нескольких комментариях говорится, что это невозможно.
Обновление 2
Я создал простой проект, который демонстрирует ошибку/неудачность генераторов последовательности именования в классе-потомке. Репозиторий находится на GitHub по этой ссылке.
Есть предложения, как заставить это работать?
Использование Spring Boot 3.4.4
Журнал консоли:

org.springframework.dao.InvalidDataAccessResourceUsageException: не удалось
извлечь ResultSet [ОШИБКА: отношение "descendant_one_id_seq"
не существует. Позиция: 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.ReflectiveMethodInvocate.proceed(ReflectiveMethodInvocate.java:184)
at
org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulationMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165)

Предок
@MappedSuperclass
public abstract class AbstractDatabaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity_generator")
protected Long id;
// other common attributes

// common methods to all descendants
}

Потомок
@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;
}
}

Потомок
@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;
}
}

Тестовый класс, демонстрирующий использование
@ServiceTest
class SequenceServiceTest {
@Autowired
DescendantOneRepository repository;
@Autowired
SequenceService cut;

@BeforeEach
void setUp() {
assertThat(cut).isNotNull();
assertThat(repository).isNotNull();
}

@Test
// @Transactional(propagation = Propagation.NOT_SUPPORTED)
void createDescendantOne() {
var result = cut.createDescendantOne();
assertThat(result).isNotNull();
}
}



Подробнее здесь: https://stackoverflow.com/questions/795 ... ss-ancesto
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»