spring-data-jpa 失效对象状态异常:行被另一个事务更新或删除(或未保存值Map不正确)超过2次

g52tjvyc  于 2022-11-10  发布在  Spring
关注(0)|答案(2)|浏览(127)

如果我手动设置DTO,基本更新工作正常。Mapper和BeanUtils.copy属性导致了过时异常

//Mapper
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
    public abstract void fromApi(CustomerDetails dto, @MappingTarget Customer entity );
or
//Beanutils

BeanUtils.copyProperties(dto, entity );

为了避免上述错误。我在MappedSuperClass中添加了以下版本。在添加版本时,应用程序无法启动。有任何想法如何更新相同的。请帮助

//update code 
public CustomerDetails updateCustomer(Long cid, CustomerDetails customerDetails) {

    Customer customer = custMenuRepository.findById(menuId).orElseThrow(
            () -> new ResourceNotFoundException("Not found"));
    custMapper.fromApi(customerDetails,customer);       

    customer = custRepository.saveAndFlush(customer);

    return custMapper.entityToApi(customer);
}

基础实体见下图:

@MappedSuperclass
@EntityListeners({AuditingEntityListener.class, AuditTrailListener.class})
public class BaseEntity {
    @Column(name = "created_by", updatable = false)
    @CreatedBy
    private String createdBy;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_date", updatable = false)
    @CreatedDate
    private Date createdDate;

    @Column(name = "modified_by")
    @LastModifiedBy
    private String modifiedBy;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "modified_date")
    @LastModifiedDate
    private Date modifiedDate;

    @Column(name = "txn_id")
    private String transactionId;

    @Column(name = "ver_id")
    @Version
    private Integer version;

实际实体:

@Entity
@Table(name = "CUSTOMER")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer extends AbstractPersistableEntity implements Serializable {

    @Id
    @Column(name = "CUST_ID", updatable = false)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_CUST")
    @SequenceGenerator(name="SEQ_CUST", sequenceName="SEQ_CUST_ID")
    private Long custId

    @Version
    @Column(name = "REVISION")
    private Integer revision;

    @Column(length = 100,name = "CUST_NAME")
    private String custName;

    @Column(length = 300,name = "CUST_DESC")
    private String description;

    @Column(length = 255,name = "CUST_PHOTO")
    private String thumbnail;

数据库配置如下

public class CustomerDBConfig extends PersistenceConfig {
    @Override
    @Bean(name = "Customer_ds")
    @ConfigurationProperties(prefix="Customer.datasource")
    public DataSource dataSource() {
        DataSource ds = null;
        if (null != isJndiEnabled) {
            JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
            ds = dataSourceLookup.getDataSource(Preconditions.checkNotNull(CustomerJNDI));
        } else {
            ds = DataSourceBuilder.create().build();
        }
        return ds;
    }

    @Override
    @Bean(name = "Customer_em")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
            @Qualifier("Customer_ds") DataSource dataSource) {
        return builder.dataSource(dataSource).packages("com.testservicecustomer.persistence")
                .persistenceUnit("Customer_punit").build();
    }

    @Override
    @Bean(name = "Customer_txnMgr")
    public PlatformTransactionManager transactionManager(
            @Qualifier("Customer_em") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

启动时出现异常

used by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'jpaMappingContext': Invocation of init
method failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'customer_em' defined in class path resource
[com/testservicecustomer/config/customerDBConfig.class]: Invocation of
init method failed; nested exception is
javax.persistence.PersistenceException: [PersistenceUnit:
customer_punit] Unable to build Hibernate SessionFactory; nested
exception is java.lang.IllegalArgumentException: Given property did
not match declared version property
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
        ... 104 common frames omitted Caused by: org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'customer_em' defined in class path resource
[com/testservicecustomer/config/customerDBConfig.class]: Invocation of
init method failed; nested exception is
javax.persistence.PersistenceException: [PersistenceUnit:
customer_punit] Unable to build Hibernate SessionFactory; nested
exception is java.lang.IllegalArgumentException: Given property did
not match declared version property
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:671)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:659)
        at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1300)
        at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:329)
        at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.getMetamodels(JpaMetamodelMappingContextFactoryBean.java:102)
        at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:80)
        at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:44)
        at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:142)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
        ... 111 common frames omitted Caused by: javax.persistence.PersistenceException: [PersistenceUnit:
customer_punit] Unable to build Hibernate SessionFactory; nested
exception is java.lang.IllegalArgumentException: Given property did
not match declared version property
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
        ... 127 common frames omitted Caused by: java.lang.IllegalArgumentException: Given property did not match
declared version property
        at org.hibernate.metamodel.internal.AttributeFactory$6.resolveMember(AttributeFactory.java:1094)
        at org.hibernate.metamodel.internal.AttributeFactory.determineAttributeMetadata(AttributeFactory.java:486)
        at org.hibernate.metamodel.internal.AttributeFactory.buildVersionAttribute(AttributeFactory.java:205)
        at org.hibernate.metamodel.internal.MetadataContext.applyVersionAttribute(MetadataContext.java:375)
        at org.hibernate.metamodel.internal.MetadataContext.wrapUp(MetadataContext.java:265)
        at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:274)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:303)
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:468)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259)
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
        ... 131 common frames omitted
oug3syen

oug3syen1#

我查找了源代码,这似乎是来自:

if ( !versionPropertyName.equals( entityMetamodel.getVersionProperty().getName() ) ) {
            // this should never happen, but to be safe...
            throw new IllegalArgumentException( "Given property did not match declared version property" );
        }

我会将throw语句上面的注解解释为Hibernate bug,即使它可能是由一些错误的配置触发的:创建一个最小复制器,并提交一个票证。
当然,您也可以在那里放置一个断点,看看在检查不同的变量(尤其是versionPropertyNameif ( !versionPropertyName.equals( entityMetamodel.getVersionProperty().getName())时是否知道哪里出了问题

x0fgdtte

x0fgdtte2#

问题是我在我的实体中使用了多个版本。修订是我们从我们的结束维护的东西。我使用它是假设它将从下一次更新开始增加修订,无论我们开始使用什么数字。
谢谢大家帮我

相关问题