Basic update is working fine if i manually set the DTO. Stale Exception is caused by Mapper and BeanUtils.copy properties

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

BeanUtils.copyProperties(dto, entity );

To avoid the above error. I added below version in MappedSuperClass. On adding version application is failed to startup. Any idea how to update the same. Please help

//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);
}

Base entity as below:

@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;

Actual Enitity:

@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;
    
  

Database config is as follows

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);
    }

Exception on startup

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
2

There are 2 best solutions below

0
On

I looked up the source code where this seems to be coming from:

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" );
        }

I'd interpret the comment above the throw statement such that this is a Hibernate bug, even if it might be triggered by some wrong configuration: Create a minimal reproducer, and submit a ticket.

Of course you might also put a break point there and see if you get an idea what is going wrong when inspecting the different variables, especially versionPropertyName vs if ( !versionPropertyName.equals( entityMetamodel.getVersionProperty().getName()

0
On

The issue was I was using multiple version in my entity. Revision is something which we maintain from our end. I used it assuming it will increment the revision from next update for whatever number we start with.

Thanks all for helping me out