java - Problem saving JPA records from a csv file in SpringBoot - Row was updated or deleted by another transaction (or unsaved-

I'm trying to make a small test project where I have News(Blog posts) and people can react to them

I'm trying to make a small test project where I have News(Blog posts) and people can react to them. I wanted to be able to load articles from a csv file and it turned out to be more complicated than I had anticipated.

Here is my News class

package com.cloakstudio.apiwyldernews.model;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import .hibernate.validator.constraints.URL;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import java.util.stream.Collectors;
@Getter
@Setter
@Entity
@Table(name = "News")
@NoArgsConstructor
@AllArgsConstructor
public class News {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "Update type cannot be empty")
    @Column(name = "update_type")
    private String updateType;

    @Column(name = "created_at")
    private Date createdAt;

    @NotBlank(message = "Title cannot be empty")
    @Column(columnDefinition = "TEXT")
    private String title;

    @NotBlank(message = "Intro cannot be empty")
    @Column(columnDefinition = "TEXT")
    private String intro;

    @NotBlank(message = "Thumbnail url cannot be empty")
    @URL(message = "Thumbnail url must be a valid url")
    @Column(name = "thumbnail_url")
    private String thumbnailUrl;

    @NotBlank(message = "Image url cannot be empty")
    @URL(message = "Image url must be a valid url")
    @Column(name = "image_url")
    private String imageUrl;

    @NotBlank(message = "Description cannot be empty")
    @Column(columnDefinition = "TEXT")
    private String description;

    @Column(name = "news_id")
    private Long newsId;

    private int snaps;

    private String location;

    @JsonManagedReference
    @OneToMany(mappedBy="news", cascade = CascadeType.ALL)
    Set<NewsReactions> newsReactions;

    public News(String updateType, String title, String intro, String thumbnailUrl, String imageUrl, String description, String location) {
        this.updateType = updateType;
        this.title = title;
        this.intro = intro;
        this.thumbnailUrl = thumbnailUrl;
        this.imageUrl = imageUrl;
        this.description = description;
        this.location = location;
    }
  //...
}

And here is the csv file I'm trying to import

id,updateType,createdAt,title,intro,thumbnailUrl,imageUrl,description,newsId,snaps,location
1,Guide,2025-03-18T09:03:59.046+00:00,How to do cool tricks,In this guide you will learn how to do cool tricks like import a csv file in java,.jpg,.jpg,Importing a csv file is a very useful feature to test your application,0,0,My personal computer

Here is the CSVObjectLoader class

package com.cloakstudio.apiwyldernews.loader;

import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import .slf4j.Logger;
import .slf4j.LoggerFactory;
import .springframework.core.io.ClassPathResource;
import .springframework.stereotype.Component;

import java.io.File;
import java.util.Collections;
import java.util.List;

@Component
public class CSVObjectLoader {
    private static final Logger logger = LoggerFactory.getLogger(CSVObjectLoader.class);

    public <T> List<T> loadObjectList(Class<T> type, String filename) {
        try {
            // The schema is based on the first row
            CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader();
            CsvMapper mapper = new CsvMapper();
            // Get the file from the class path
            File file = new ClassPathResource(filename).getFile();
            // Read the values
            MappingIterator<T> readValues = mapper.reader(type).with(bootstrapSchema).readValues(file);
            return readValues.readAll();
        } catch(Exception e) {
            logger.error("An error has occurred while trying to read the following file : " + filename, e);
            return Collections.emptyList();
        }
    }
}

InitialDataLoader class

package com.cloakstudio.apiwyldernews.loader;

import com.cloakstudio.apiwyldernews.model.News;
import .springframework.beans.factory.annotation.Autowired;
import .springframework.stereotype.Component;

import java.util.List;

@Component
public class InitialDataLoader {
    @Autowired
    CSVObjectLoader csvObjectLoader;

    String NEWS_FILE = "newsList.csv";

    public List<News> getNews() {
        return csvObjectLoader.loadObjectList(News.class, NEWS_FILE);
    }
}

InitialDataSetupService class

package com.cloakstudio.apiwyldernews.loader;

import com.cloakstudio.apiwyldernews.model.News;
import com.cloakstudio.apiwyldernews.repository.NewsRepository;
import .springframework.beans.factory.annotation.Autowired;
import .springframework.stereotype.Component;

@Component
public class InitialDataSetupService {

    @Autowired
    NewsRepository newsRepository;

    public void setupNews(News news) {
        if(!newsRepository.existsById(news.getId())) {
            newsRepository.save(news);
        }
    }
}

InitialDataSetup class

package com.cloakstudio.apiwyldernews.loader;

import com.cloakstudio.apiwyldernews.model.News;
import jakarta.annotation.PostConstruct;
import .springframework.beans.factory.annotation.Autowired;
import .springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

@Component
public class InitialDataSetup {
    @Autowired
    InitialDataLoader initialDataLoader;

    @Autowired
    InitialDataSetupService initialDataSetupService;

    @PostConstruct
    private void setupData() {
        setupInitialData();
    }

    public void setupInitialData() {
        List<News> newsList = initialDataLoader.getNews();
        for(News news : newsList) {
            initialDataSetupService.setupNews(news);
        }
    }
}

And I'm getting the following error in the console :

2025-03-21T09:23:30.786+01:00 ERROR 14519 --- [apiwyldernews] [           main] o.s.boot.SpringApplication               : Application run failed

.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initialDataSetup': Invocation of init method failed
    at .springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:222) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:423) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:346) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1155) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1121) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1056) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.3.jar:6.2.3]
    at .springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.3.jar:6.2.3]
    at .springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.4.3.jar:3.4.3]
    at com.cloakstudio.apiwyldernews.ApiwyldernewsApplication.main(ApiwyldernewsApplication.java:10) ~[classes/:na]
Caused by: .springframework.orm.ObjectOptimisticLockingFailureException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.cloakstudio.apiwyldernews.model.News#1]
    at .springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:325) ~[spring-orm-6.2.3.jar:6.2.3]
    at .springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244) ~[spring-orm-6.2.3.jar:6.2.3]
    at .springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:560) ~[spring-orm-6.2.3.jar:6.2.3]
    at .springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:343) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:160) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165) ~[spring-data-jpa-3.4.3.jar:3.4.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.3.jar:6.2.3]
    at jdk.proxy2/jdk.proxy2.$Proxy144.save(Unknown Source) ~[na:na]
    at com.cloakstudio.apiwyldernews.loader.InitialDataSetupService.setupNews(InitialDataSetupService.java:27) ~[classes/:na]
    at com.cloakstudio.apiwyldernews.loader.InitialDataSetup.setupInitialData(InitialDataSetup.java:35) ~[classes/:na]
    at com.cloakstudio.apiwyldernews.loader.InitialDataSetup.setupData(InitialDataSetup.java:22) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at .springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMethod.invoke(InitDestroyAnnotationBeanPostProcessor.java:457) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:401) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:219) ~[spring-beans-6.2.3.jar:6.2.3]
    ... 20 common frames omitted
Caused by: .hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.cloakstudio.apiwyldernews.model.News#1]
    at .hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:426) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.internal.DefaultMergeEventListener.merge(DefaultMergeEventListener.java:214) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.internal.DefaultMergeEventListener.doMerge(DefaultMergeEventListener.java:152) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:136) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:89) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:854) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.internal.SessionImpl.merge(SessionImpl.java:840) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at .springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:320) ~[spring-orm-6.2.3.jar:6.2.3]
    at jdk.proxy2/jdk.proxy2.$Proxy141.merge(Unknown Source) ~[na:na]
    at .springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:639) ~[spring-data-jpa-3.4.3.jar:3.4.3]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at .springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:277) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:515) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:284) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:752) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:174) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:149) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:69) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:380) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138) ~[spring-tx-6.2.3.jar:6.2.3]
    ... 33 common frames omitted

Disconnected from the target VM, address: '127.0.0.1:59353', transport: 'socket'

Process finished with exit code 1

I'm using the following tutorial in order to load the csv Baeldung tutorial

I'm trying to make a small test project where I have News(Blog posts) and people can react to them. I wanted to be able to load articles from a csv file and it turned out to be more complicated than I had anticipated.

Here is my News class

package com.cloakstudio.apiwyldernews.model;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import .hibernate.validator.constraints.URL;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import java.util.stream.Collectors;
@Getter
@Setter
@Entity
@Table(name = "News")
@NoArgsConstructor
@AllArgsConstructor
public class News {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "Update type cannot be empty")
    @Column(name = "update_type")
    private String updateType;

    @Column(name = "created_at")
    private Date createdAt;

    @NotBlank(message = "Title cannot be empty")
    @Column(columnDefinition = "TEXT")
    private String title;

    @NotBlank(message = "Intro cannot be empty")
    @Column(columnDefinition = "TEXT")
    private String intro;

    @NotBlank(message = "Thumbnail url cannot be empty")
    @URL(message = "Thumbnail url must be a valid url")
    @Column(name = "thumbnail_url")
    private String thumbnailUrl;

    @NotBlank(message = "Image url cannot be empty")
    @URL(message = "Image url must be a valid url")
    @Column(name = "image_url")
    private String imageUrl;

    @NotBlank(message = "Description cannot be empty")
    @Column(columnDefinition = "TEXT")
    private String description;

    @Column(name = "news_id")
    private Long newsId;

    private int snaps;

    private String location;

    @JsonManagedReference
    @OneToMany(mappedBy="news", cascade = CascadeType.ALL)
    Set<NewsReactions> newsReactions;

    public News(String updateType, String title, String intro, String thumbnailUrl, String imageUrl, String description, String location) {
        this.updateType = updateType;
        this.title = title;
        this.intro = intro;
        this.thumbnailUrl = thumbnailUrl;
        this.imageUrl = imageUrl;
        this.description = description;
        this.location = location;
    }
  //...
}

And here is the csv file I'm trying to import

id,updateType,createdAt,title,intro,thumbnailUrl,imageUrl,description,newsId,snaps,location
1,Guide,2025-03-18T09:03:59.046+00:00,How to do cool tricks,In this guide you will learn how to do cool tricks like import a csv file in java,https://media.fromsoftware.jp/eldenring/resources/images/movieandimages/screenshot/thumb/10.jpg,https://media.fromsoftware.jp/eldenring/resources/images/movieandimages/screenshot/4k/10.jpg,Importing a csv file is a very useful feature to test your application,0,0,My personal computer

Here is the CSVObjectLoader class

package com.cloakstudio.apiwyldernews.loader;

import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import .slf4j.Logger;
import .slf4j.LoggerFactory;
import .springframework.core.io.ClassPathResource;
import .springframework.stereotype.Component;

import java.io.File;
import java.util.Collections;
import java.util.List;

@Component
public class CSVObjectLoader {
    private static final Logger logger = LoggerFactory.getLogger(CSVObjectLoader.class);

    public <T> List<T> loadObjectList(Class<T> type, String filename) {
        try {
            // The schema is based on the first row
            CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader();
            CsvMapper mapper = new CsvMapper();
            // Get the file from the class path
            File file = new ClassPathResource(filename).getFile();
            // Read the values
            MappingIterator<T> readValues = mapper.reader(type).with(bootstrapSchema).readValues(file);
            return readValues.readAll();
        } catch(Exception e) {
            logger.error("An error has occurred while trying to read the following file : " + filename, e);
            return Collections.emptyList();
        }
    }
}

InitialDataLoader class

package com.cloakstudio.apiwyldernews.loader;

import com.cloakstudio.apiwyldernews.model.News;
import .springframework.beans.factory.annotation.Autowired;
import .springframework.stereotype.Component;

import java.util.List;

@Component
public class InitialDataLoader {
    @Autowired
    CSVObjectLoader csvObjectLoader;

    String NEWS_FILE = "newsList.csv";

    public List<News> getNews() {
        return csvObjectLoader.loadObjectList(News.class, NEWS_FILE);
    }
}

InitialDataSetupService class

package com.cloakstudio.apiwyldernews.loader;

import com.cloakstudio.apiwyldernews.model.News;
import com.cloakstudio.apiwyldernews.repository.NewsRepository;
import .springframework.beans.factory.annotation.Autowired;
import .springframework.stereotype.Component;

@Component
public class InitialDataSetupService {

    @Autowired
    NewsRepository newsRepository;

    public void setupNews(News news) {
        if(!newsRepository.existsById(news.getId())) {
            newsRepository.save(news);
        }
    }
}

InitialDataSetup class

package com.cloakstudio.apiwyldernews.loader;

import com.cloakstudio.apiwyldernews.model.News;
import jakarta.annotation.PostConstruct;
import .springframework.beans.factory.annotation.Autowired;
import .springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

@Component
public class InitialDataSetup {
    @Autowired
    InitialDataLoader initialDataLoader;

    @Autowired
    InitialDataSetupService initialDataSetupService;

    @PostConstruct
    private void setupData() {
        setupInitialData();
    }

    public void setupInitialData() {
        List<News> newsList = initialDataLoader.getNews();
        for(News news : newsList) {
            initialDataSetupService.setupNews(news);
        }
    }
}

And I'm getting the following error in the console :

2025-03-21T09:23:30.786+01:00 ERROR 14519 --- [apiwyldernews] [           main] o.s.boot.SpringApplication               : Application run failed

.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initialDataSetup': Invocation of init method failed
    at .springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:222) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:423) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:346) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1155) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1121) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1056) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.3.jar:6.2.3]
    at .springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.3.jar:6.2.3]
    at .springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.4.3.jar:3.4.3]
    at .springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.4.3.jar:3.4.3]
    at com.cloakstudio.apiwyldernews.ApiwyldernewsApplication.main(ApiwyldernewsApplication.java:10) ~[classes/:na]
Caused by: .springframework.orm.ObjectOptimisticLockingFailureException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.cloakstudio.apiwyldernews.model.News#1]
    at .springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:325) ~[spring-orm-6.2.3.jar:6.2.3]
    at .springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244) ~[spring-orm-6.2.3.jar:6.2.3]
    at .springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:560) ~[spring-orm-6.2.3.jar:6.2.3]
    at .springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:343) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:160) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165) ~[spring-data-jpa-3.4.3.jar:3.4.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.3.jar:6.2.3]
    at jdk.proxy2/jdk.proxy2.$Proxy144.save(Unknown Source) ~[na:na]
    at com.cloakstudio.apiwyldernews.loader.InitialDataSetupService.setupNews(InitialDataSetupService.java:27) ~[classes/:na]
    at com.cloakstudio.apiwyldernews.loader.InitialDataSetup.setupInitialData(InitialDataSetup.java:35) ~[classes/:na]
    at com.cloakstudio.apiwyldernews.loader.InitialDataSetup.setupData(InitialDataSetup.java:22) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at .springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMethod.invoke(InitDestroyAnnotationBeanPostProcessor.java:457) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:401) ~[spring-beans-6.2.3.jar:6.2.3]
    at .springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:219) ~[spring-beans-6.2.3.jar:6.2.3]
    ... 20 common frames omitted
Caused by: .hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.cloakstudio.apiwyldernews.model.News#1]
    at .hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:426) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.internal.DefaultMergeEventListener.merge(DefaultMergeEventListener.java:214) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.internal.DefaultMergeEventListener.doMerge(DefaultMergeEventListener.java:152) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:136) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:89) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:854) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at .hibernate.internal.SessionImpl.merge(SessionImpl.java:840) ~[hibernate-core-6.6.8.Final.jar:6.6.8.Final]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at .springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:320) ~[spring-orm-6.2.3.jar:6.2.3]
    at jdk.proxy2/jdk.proxy2.$Proxy141.merge(Unknown Source) ~[na:na]
    at .springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:639) ~[spring-data-jpa-3.4.3.jar:3.4.3]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at .springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:277) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:515) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:284) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:752) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:174) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:149) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:69) ~[spring-data-commons-3.4.3.jar:3.4.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:380) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.2.3.jar:6.2.3]
    at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
    at .springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138) ~[spring-tx-6.2.3.jar:6.2.3]
    ... 33 common frames omitted

Disconnected from the target VM, address: '127.0.0.1:59353', transport: 'socket'

Process finished with exit code 1

I'm using the following tutorial in order to load the csv Baeldung tutorial

Share Improve this question edited Mar 21 at 14:44 John Williams 5,5552 gold badges10 silver badges25 bronze badges asked Mar 21 at 8:50 GwendalGwendal 514 bronze badges 3
  • Still using java.util.Date? Don’t! Your example created at, 2025-03-18T09:03:59.046+00:00, fits nicely with an OffsetDateTime from java.time, the modern Java date and time API. Which I strongly recommend. – Anonymous Commented Mar 21 at 10:46
  • It’s a lot of code. Please consider if you can create a minimal reproducible example. – Anonymous Commented Mar 21 at 10:47
  • 1 I ended up figuring it out, see tmy answer below. – Gwendal Commented Mar 21 at 12:50
Add a comment  | 

1 Answer 1

Reset to default 1

Alright. I found it thanks to this article Medium article. Basically I add to set the id to null before saving it, but because of the constraints on my Class I needed to have an id in the csv file for the csv parsing

So in the setup method I did :

public void setupNews(News news) {
        news.setId(null);
        newsRepository.save(news);
        }
    }

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744365457a4570681.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信