Handling Errors When Importing CSV Data into a Database in Spring Boot
When building modern web applications, the ability to import data from external files like CSV into a database is a common requirement. However, this process often introduces various challenges that, if not handled properly, can result in corrupt...

- Invalid Data: Missing fields, incorrect formats, or unsupported characters.
- Duplicate Entries: Repeated records that violate unique constraints.
- Large File Sizes: Overloading memory when dealing with millions of records.
- Concurrency Issues: Multiple users uploading files simultaneously.
- Partial Failures: Some records succeed while others fail, leaving the database in an inconsistent state.
@Component
public class CSVReader {
public List<String[]> readCSV(String filePath) throws IOException {
List<String[]> data = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
String[] values = line.split(",");
data.add(values);
}
} catch (IOException e) {
throw new IOException("Error reading CSV file: " + e.getMessage(), e);
}
return data;
}
}
- BufferedReader is used to read the file line by line.
- Lines are split using commas, but this is a simplistic approach and may fail for quoted fields or escaped commas.
public class CSVRecord {
@NotBlank(message = "Name cannot be blank")
private String name;
@Email(message = "Invalid email format")
private String email;
@Pattern(regexp = "\d{10}", message = "Phone number must be 10 digits")
private String phone;
// Getters and Setters
}
@Service
public class CSVProcessor {
public void validateAndSave(List<String[]> records) {
for (String[] record : records) {
try {
CSVRecord csvRecord = mapToRecord(record);
validate(csvRecord);
saveToDatabase(csvRecord);
} catch (ConstraintViolationException e) {
logError(record, e);
}
}
}
private CSVRecord mapToRecord(String[] record) {
CSVRecord csvRecord = new CSVRecord();
csvRecord.setName(record[0]);
csvRecord.setEmail(record[1]);
csvRecord.setPhone(record[2]);
return csvRecord;
}
private void validate(CSVRecord csvRecord) {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<CSVRecord>> violations = validator.validate(csvRecord);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
private void saveToDatabase(CSVRecord csvRecord) {
// Save to the database logic
}
private void logError(String[] record, Exception e) {
System.err.println("Error processing record: " + Arrays.toString(record) + " - " + e.getMessage());
}
}
@Transactional
public void saveToDatabase(CSVRecord csvRecord) {
Optional<User> existingUser = userRepository.findByEmail(csvRecord.getEmail());
if (existingUser.isPresent()) {
System.out.println("Duplicate record found: " + csvRecord.getEmail());
return; // Skip or update existing record
}
userRepository.save(csvRecord.toEntity());
}
public void processLargeCSV(String filePath) throws IOException {
try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
lines.skip(1) // Skip header
.map(this::parseLine)
.forEach(this::processRecord);
}
}
private void processRecord(String[] record) {
try {
// Process each record
} catch (Exception e) {
// Handle errors
}
}
private void logError(String[] record, Exception e) {
logger.error("Error processing record: {} - {}", Arrays.toString(record), e.getMessage());
}
@Retryable(
value = {SQLException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 2000)
)
public void saveToDatabaseWithRetry(CSVRecord csvRecord) {
userRepository.save(csvRecord.toEntity());
}
@Transactional
public void importCSV(String filePath) {
List<String[]> records = csvReader.readCSV(filePath);
for (String[] record : records) {
try {
saveToDatabase(mapToRecord(record));
} catch (Exception e) {
throw new RuntimeException("Failed to process record: " + Arrays.toString(record), e);
}
}
}
Read more at : Handling Errors When Importing CSV Data into a Database in Spring Boot
About the author
I am Tuanh.net. As of 2024, I have accumulated 8 years of experience in backend programming. I am delighted to connect and share my knowledge with everyone.
Comments
Join the discussionNo comments yet. Be the first to comment.





