не удалось удалить строки коллекции: индекс столбца находится вне диапазона

#java #postgresql #hibernate #exception

#java #postgresql #спящий режим #исключение

Вопрос:

У меня есть следующие классы гибернации:

‘Skill’ имеет много ‘SkillTranslation’, которые расширяют ‘ResourceTranslation’

Навык:

 @Entity
@Table(name = "skill")
@ToString
@Getter
@Setter
public class Skill {
    @Id
    private String id;
   
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "key", referencedColumnName = "id")
    private Set<SkillTranslation> localizedDescription;
}
 

SkillTranslation:

 @Entity
@Table(name = "skill_translation")
public class SkillTranslation extends ResourceTranslation{
}
 

ResourceTranslation:

 @ToString
@Getter
@Setter
@MappedSuperclass
@IdClass(ResourceTranslation.PK.class)
public class ResourceTranslation implements Serializable {

    @Id
    private String key;
    @Id
    @Enumerated(EnumType.STRING)
    private Locale locale;
    @Column(length = 10000)
    private String value;


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class PK implements Serializable {
        private String key;
        @Enumerated(EnumType.STRING)
        private Locale locale;
    }
}
 

Проблема возникает, когда я пытаюсь обновить существующий навык (начальная версия имеет 3 локализованных описания, а новая — только 2)

Трассировка стека:

 org.springframework.dao.DataIntegrityViolationException: could not delete collection rows: [hidden.Skill.localizedDescription#71f13be5-c692-46d3-875c-62d0905bb5ba]; SQL [update skill_translation set key=null where key=? and locale=?]; nested exception is org.hibernate.exception.DataException: could not delete collection rows: [hidden.Skill.localizedDescription#71f13be5-c692-46d3-875c-62d0905bb5ba]
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:302)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:538)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:633)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:386)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at hidden.ImportSkillsService$EnhancerBySpringCGLIB$2d832c5f.importSkills(<generated>)
    at hidden.syncAll(hidden.java:21)
    at hidden.job.RefreshAllJob.refresh(RefreshAllJob.java:22)
    at hidden.BaseRefreshJob.run(BaseRefreshJob.java:33)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.hibernate.exception.DataException: could not delete collection rows: [hidden.Skill.localizedDescription#71f13be5-c692-46d3-875c-62d0905bb5ba]
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:115)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.persister.collection.AbstractCollectionPersister.deleteRows(AbstractCollectionPersister.java:1509)
    at org.hibernate.action.internal.CollectionUpdateAction.execute(CollectionUpdateAction.java:87)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
    at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
    at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1363)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:454)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3213)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2381)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:534)
    ... 17 common frames omitted
Caused by: org.postgresql.util.PSQLException: The column index is out of range: 3, number of columns: 2.
    at org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:65)
    at org.postgresql.core.v3.SimpleParameterList.setStringParameter(SimpleParameterList.java:128)
    at org.postgresql.jdbc.PgPreparedStatement.bindString(PgPreparedStatement.java:1019)
    at org.postgresql.jdbc.PgPreparedStatement.setString(PgPreparedStatement.java:343)
    at org.postgresql.jdbc.PgPreparedStatement.setString(PgPreparedStatement.java:330)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setString(HikariProxyPreparedStatement.java)
    at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$1.doBind(VarcharTypeDescriptor.java:46)
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:73)
    at org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter.writeValue(NamedEnumValueConverter.java:75)
    at org.hibernate.type.EnumType.nullSafeSet(EnumType.java:262)
    at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:170)
    at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:365)
    at org.hibernate.type.EntityType.nullSafeSet(EntityType.java:280)
    at org.hibernate.persister.collection.AbstractCollectionPersister.writeElementToWhere(AbstractCollectionPersister.java:959)
    at org.hibernate.persister.collection.AbstractCollectionPersister.deleteRows(AbstractCollectionPersister.java:1473)
    ... 35 common frames omitted
 

Версия гибернации: 5.4.20.Final

Комментарии:

1. when I try to update an existing skill — пожалуйста, покажите, как вы это делаете.

2. Locale не является перечислением, поэтому вы не можете использовать @Enumerated . Удалите эту аннотацию. В любом случае он будет отображен как строка в режиме гибернации. Кроме того, я думаю, вы перепутали порядок столбцов. Используйте @JoinColumn(name = "id", referencedColumnName = "key")

3. @ChristianBeikov, Locale — это внутреннее перечисление проекта, я еще раз проверил JoinColumn, и он кажется действительным, «ключ» из ResourceTranslation ссылается на «id» в навыке

4. Хм, вы правы. Вы должны создать проблему в отслеживателе проблем ( hibernate.atlassian.net ) с тестовым примером ( github.com/hibernate/hibernate-test-case-templates/blob/master /… ), который воспроизводит проблему.