Spring Data JPA: org.hibernate.StaleStateException: пакетное обновление вернуло неожиданное количество строк из обновления [0];фактическое количество строк: 0;ожидается: 1 - PullRequest
0 голосов
/ 21 мая 2018

Я часто получаю эту ошибку в своих журналах, когда пытаюсь обновить свою сущность. Интересно, что когда я проверяю свою БД, я вижу, что сущность успешно обновляется с той же отметкой времени, что и журналы. Также я не могу воспроизвести проблему, когда пытаюсь выполнить тот же запрос на обновление локально.

Сущность выглядит следующим образом:

Класс Supper для MySqlAbstractEntity

@MappedSuperclass
public abstract class MysqlAbstractEntity<ID extends Serializable> implements AbstractEntity<ID> {
    private static final long serialVersionUID = 8920812256547697337L;


    @Id
    @GeneratedValue(
        generator = "myGenerator",
        strategy = GenerationType.SEQUENCE
    )
    @GenericGenerator(
        name = "myGenerator",
        strategy = "com.****.MysqlLongIDGenerator"
    )
    @Column(
        name = "id",
        updatable = false,
        insertable = false
    )
    protected Long id;
    @Temporal(TemporalType.TIMESTAMP)
    @Column(
        name = "created_on",
        nullable = false,
        updatable = false
    )
    protected Date createdOn;
    @Temporal(TemporalType.TIMESTAMP)
    @Column(
        name = "last_modified_on",
        nullable = false
    )
    protected Date lastModifiedOn;
    @Version
    @Column(
        name = "version"
    )
    protected Long version = Long.valueOf(0L);

    public MysqlAbstractEntity() {
    }

    @PrePersist
    protected void onCreate() {
        this.lastModifiedOn = this.createdOn = this.createdOn == null?new Date():this.createdOn;
    }

    @PreUpdate
    protected void onUpdate() {
        this.lastModifiedOn = new Date();
    }

Мой генератор пользовательских идентификаторов выглядит следующим образом:

public class MysqlLongIDGenerator extends IdentityGenerator {
    public MysqlLongIDGenerator() {
    }

    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object) {
        try {
            LongIDAbstractEntity entity = (LongIDAbstractEntity)object;
            if(entity.getId() != null && entity.getId().longValue() > 0L) {
                return entity.getId();
            }
        } catch (Exception var4) {
            ;
        }

        return super.generate(session, object);
    }
}

Моя действительная сущность

public class MyEntity extends MysqlAbstractEntity {
    @OneToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "other_entity_id", nullable = false)
    private SomeOtherEntity user;

    @Column(name = "active")
    private Boolean active;

    @Column(name = "device_type")
    @Enumerated(EnumType.STRING)
    private DeviceType deviceType;

    @Column(name = "app_version")
    private String appVersion;

    @Column(name = "device_id")
    private String deviceId;

    @Column(name = "device_version")
    private String deviceVersion;

    @Column(name = "client_id")
    private String clientId;
}

Мой репозиторий

@Transactional(rollbackFor = Exception.class)
public class MyEntityRepository extends CrudRepository<MyEntity, Long> {
}

И мой код обновления выглядит следующим образом:

public MyEntity update(@NotNull MyEntity updatedMyEntity) {
        MyEntity entity = myEntityRepository.findByDeviceId(updatedMyEntity.getDeviceId());
        if (entity != null) {
            return myEntityRepository.save(updateEntity(entity, updatedMyEntity));
        } else {
            return null;
        }
}

Метод updateEntity фактически обновляет значения полей

Это исключение, которое я получаю в своих логах

ObjectOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1, stackTrace org.springframework.orm.ObjectOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:320)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy118.save(Unknown Source)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...