Skip to content

Remove DbActionExecutionException #1956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,21 @@
*/
package org.springframework.data.jdbc.core;

import org.springframework.dao.OptimisticLockingFailureException;
import java.util.List;

import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.relational.core.conversion.AggregateChange;
import org.springframework.data.relational.core.conversion.DbAction;
import org.springframework.data.relational.core.conversion.DbActionExecutionException;
import org.springframework.data.relational.core.conversion.MutableAggregateChange;

import java.util.List;

/**
* Executes an {@link MutableAggregateChange}.
*
* @author Jens Schauder
* @author Myeonghyeon Lee
* @author Chirag Tailor
* @author Mikhail Polivakha
* @since 2.0
*/
class AggregateChangeExecutor {
Expand Down Expand Up @@ -79,43 +78,34 @@ <T> void executeDelete(AggregateChange<T> aggregateChange) {
}

private void execute(DbAction<?> action, JdbcAggregateChangeExecutionContext executionContext) {

try {
if (action instanceof DbAction.InsertRoot<?> insertRoot) {
executionContext.executeInsertRoot(insertRoot);
} else if (action instanceof DbAction.BatchInsertRoot<?> batchInsertRoot) {
executionContext.executeBatchInsertRoot(batchInsertRoot);
} else if (action instanceof DbAction.Insert<?> insert) {
executionContext.executeInsert(insert);
} else if (action instanceof DbAction.BatchInsert<?> batchInsert) {
executionContext.executeBatchInsert(batchInsert);
} else if (action instanceof DbAction.UpdateRoot<?> updateRoot) {
executionContext.executeUpdateRoot(updateRoot);
} else if (action instanceof DbAction.Delete<?> delete) {
executionContext.executeDelete(delete);
} else if (action instanceof DbAction.BatchDelete<?> batchDelete) {
executionContext.executeBatchDelete(batchDelete);
} else if (action instanceof DbAction.DeleteAll<?> deleteAll) {
executionContext.executeDeleteAll(deleteAll);
} else if (action instanceof DbAction.DeleteRoot<?> deleteRoot) {
executionContext.executeDeleteRoot(deleteRoot);
} else if (action instanceof DbAction.BatchDeleteRoot<?> batchDeleteRoot) {
executionContext.executeBatchDeleteRoot(batchDeleteRoot);
} else if (action instanceof DbAction.DeleteAllRoot<?> deleteAllRoot) {
executionContext.executeDeleteAllRoot(deleteAllRoot);
} else if (action instanceof DbAction.AcquireLockRoot<?> acquireLockRoot) {
executionContext.executeAcquireLock(acquireLockRoot);
} else if (action instanceof DbAction.AcquireLockAllRoot<?> acquireLockAllRoot) {
executionContext.executeAcquireLockAllRoot(acquireLockAllRoot);
} else {
throw new RuntimeException("unexpected action");
}
} catch (Exception e) {

if (e instanceof OptimisticLockingFailureException) {
throw e;
}
throw new DbActionExecutionException(action, e);
if (action instanceof DbAction.InsertRoot<?> insertRoot) {
executionContext.executeInsertRoot(insertRoot);
} else if (action instanceof DbAction.BatchInsertRoot<?> batchInsertRoot) {
executionContext.executeBatchInsertRoot(batchInsertRoot);
} else if (action instanceof DbAction.Insert<?> insert) {
executionContext.executeInsert(insert);
} else if (action instanceof DbAction.BatchInsert<?> batchInsert) {
executionContext.executeBatchInsert(batchInsert);
} else if (action instanceof DbAction.UpdateRoot<?> updateRoot) {
executionContext.executeUpdateRoot(updateRoot);
} else if (action instanceof DbAction.Delete<?> delete) {
executionContext.executeDelete(delete);
} else if (action instanceof DbAction.BatchDelete<?> batchDelete) {
executionContext.executeBatchDelete(batchDelete);
} else if (action instanceof DbAction.DeleteAll<?> deleteAll) {
executionContext.executeDeleteAll(deleteAll);
} else if (action instanceof DbAction.DeleteRoot<?> deleteRoot) {
executionContext.executeDeleteRoot(deleteRoot);
} else if (action instanceof DbAction.BatchDeleteRoot<?> batchDeleteRoot) {
executionContext.executeBatchDeleteRoot(batchDeleteRoot);
} else if (action instanceof DbAction.DeleteAllRoot<?> deleteAllRoot) {
executionContext.executeDeleteAllRoot(deleteAllRoot);
} else if (action instanceof DbAction.AcquireLockRoot<?> acquireLockRoot) {
executionContext.executeAcquireLock(acquireLockRoot);
} else if (action instanceof DbAction.AcquireLockAllRoot<?> acquireLockAllRoot) {
executionContext.executeAcquireLockAllRoot(acquireLockAllRoot);
} else {
throw new RuntimeException("unexpected action");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -563,9 +563,8 @@ void updateFailedRootDoesNotExist() {
LegoSet entity = new LegoSet();
entity.id = 100L; // does not exist in the database

assertThatExceptionOfType(DbActionExecutionException.class) //
.isThrownBy(() -> template.save(entity)) //
.withCauseInstanceOf(IncorrectUpdateSemanticsDataAccessException.class);
assertThatExceptionOfType(IncorrectUpdateSemanticsDataAccessException.class) //
.isThrownBy(() -> template.save(entity));
}

@Test // DATAJDBC-112
Expand Down Expand Up @@ -1165,7 +1164,7 @@ void saveAndUpdateAggregateWithIdAndNullVersion() {
aggregate.setVersion(null);
aggregate.setId(23L);

assertThatThrownBy(() -> template.save(aggregate)).isInstanceOf(DbActionExecutionException.class);
assertThatThrownBy(() -> template.save(aggregate)).isInstanceOf(IncorrectUpdateSemanticsDataAccessException.class);
}

@Test // DATAJDBC-462
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
*
* @author Myeonghyeon Lee
* @author Jens Schauder
* @author Mikhail Polivakha
*/
@ExtendWith(SpringExtension.class)
public class JdbcRepositoryConcurrencyIntegrationTests {
Expand Down Expand Up @@ -159,7 +160,7 @@ public void concurrentUpdateAndDelete() throws Exception {
} catch (Exception ex) {
// When the delete execution is complete, the Update execution throws an
// IncorrectUpdateSemanticsDataAccessException.
if (ex.getCause() instanceof IncorrectUpdateSemanticsDataAccessException) {
if (ex instanceof IncorrectUpdateSemanticsDataAccessException) {
return null;
}
throw ex;
Expand Down Expand Up @@ -193,7 +194,7 @@ public void concurrentUpdateAndDeleteAll() throws Exception {
} catch (Exception ex) {
// When the delete execution is complete, the Update execution throws an
// IncorrectUpdateSemanticsDataAccessException.
if (ex.getCause() instanceof IncorrectUpdateSemanticsDataAccessException) {
if (ex instanceof IncorrectUpdateSemanticsDataAccessException) {
return null;
}
throw ex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
*/
package org.springframework.data.jdbc.repository;

import static java.util.Arrays.*;
import static java.util.Collections.*;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.SoftAssertions.*;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.SoftAssertions.assertSoftly;

import java.io.IOException;
import java.sql.ResultSet;
Expand All @@ -37,6 +39,7 @@
import java.util.function.Consumer;
import java.util.stream.Stream;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand All @@ -49,9 +52,21 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ClassPathResource;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.*;
import org.springframework.data.annotation.Transient;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Limit;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Persistable;
import org.springframework.data.domain.ScrollPosition;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Window;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.jdbc.repository.query.Modifying;
import org.springframework.data.jdbc.repository.query.Query;
Expand All @@ -64,8 +79,8 @@
import org.springframework.data.jdbc.testing.TestDatabaseFeatures;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.MappedCollection;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.relational.core.mapping.Sequence;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.relational.core.mapping.event.AbstractRelationalEvent;
import org.springframework.data.relational.core.mapping.event.AfterConvertEvent;
import org.springframework.data.relational.core.sql.LockMode;
Expand Down Expand Up @@ -104,6 +119,8 @@ public class JdbcRepositoryIntegrationTests {

@Autowired NamedParameterJdbcTemplate template;
@Autowired DummyEntityRepository repository;

@Autowired ProvidedIdEntityRepository providedIdEntityRepository;
@Autowired MyEventListener eventListener;
@Autowired RootRepository rootRepository;
@Autowired WithDelimitedColumnRepository withDelimitedColumnRepository;
Expand Down Expand Up @@ -208,6 +225,18 @@ public void findAllFindsAllSpecifiedEntities() {
.containsExactlyInAnyOrder(entity.getIdProp(), other.getIdProp());
}

@Test // DATAJDBC-611
public void testDuplicateKeyExceptionIsThrownInCaseOfUniqueKeyViolation() {

// given.
ProvidedIdEntity first = ProvidedIdEntity.newInstance(1L, "name");
ProvidedIdEntity second = ProvidedIdEntity.newInstance(1L, "other");

// when/then
Assertions.assertThatCode(() -> providedIdEntityRepository.save(first)).doesNotThrowAnyException();
Assertions.assertThatThrownBy(() -> providedIdEntityRepository.save(second)).isInstanceOf(DuplicateKeyException.class);
}

@Test // DATAJDBC-97
public void countsEntities() {

Expand Down Expand Up @@ -1436,6 +1465,10 @@ interface DummyProjectExample {
String getName();
}

interface ProvidedIdEntityRepository extends CrudRepository<ProvidedIdEntity, Long> {

}

interface DummyEntityRepository extends CrudRepository<DummyEntity, Long>, QueryByExampleExecutor<DummyEntity> {

@Lock(LockMode.PESSIMISTIC_WRITE)
Expand Down Expand Up @@ -1543,6 +1576,11 @@ DummyEntityRepository dummyEntityRepository() {
return factory.getRepository(DummyEntityRepository.class);
}

@Bean
ProvidedIdEntityRepository providedIdEntityRepository() {
return factory.getRepository(ProvidedIdEntityRepository.class);
}

@Bean
RootRepository rootRepository() {
return factory.getRepository(RootRepository.class);
Expand Down Expand Up @@ -1886,6 +1924,37 @@ public String getName() {
}
}

static class ProvidedIdEntity implements Persistable<Long> {

@Id
private final Long id;

private String name;

@Transient
private boolean isNew;

private ProvidedIdEntity(Long id, String name, boolean isNew) {
this.id = id;
this.name = name;
this.isNew = isNew;
}

private static ProvidedIdEntity newInstance(Long id, String name) {
return new ProvidedIdEntity(id, name, true);
}

@Override
public Long getId() {
return id;
}

@Override
public boolean isNew() {
return isNew;
}
}

static class DummyEntity {

String name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ DROP TABLE LEAF;
DROP TABLE WITH_DELIMITED_COLUMN;
DROP TABLE ENTITY_WITH_SEQUENCE;
DROP SEQUENCE ENTITY_SEQUENCE;
DROP TABLE PROVIDED_ID_ENTITY;

CREATE TABLE dummy_entity
(
Expand Down Expand Up @@ -55,4 +56,8 @@ CREATE TABLE ENTITY_WITH_SEQUENCE
NAME VARCHAR(100)
);

CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;
CREATE TABLE PROVIDED_ID_ENTITY
(
ID BIGINT PRIMARY KEY,
NAME VARCHAR(30)
);
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,10 @@ CREATE TABLE ENTITY_WITH_SEQUENCE
NAME VARCHAR(100)
);

CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

CREATE TABLE PROVIDED_ID_ENTITY
(
ID BIGINT PRIMARY KEY,
NAME VARCHAR(30)
);
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,10 @@ CREATE TABLE ENTITY_WITH_SEQUENCE
NAME VARCHAR(100)
);

CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

CREATE TABLE PROVIDED_ID_ENTITY
(
ID BIGINT PRIMARY KEY,
NAME VARCHAR(30)
);
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,10 @@ CREATE TABLE ENTITY_WITH_SEQUENCE
NAME VARCHAR(100)
);

CREATE SEQUENCE `ENTITY_SEQUENCE` START WITH 1 INCREMENT BY 1 NO MAXVALUE;
CREATE SEQUENCE `ENTITY_SEQUENCE` START WITH 1 INCREMENT BY 1 NO MAXVALUE;

CREATE TABLE PROVIDED_ID_ENTITY
(
ID BIGINT PRIMARY KEY,
NAME VARCHAR(30)
);
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ DROP TABLE IF EXISTS LEAF;
DROP TABLE IF EXISTS WITH_DELIMITED_COLUMN;
DROP TABLE IF EXISTS ENTITY_WITH_SEQUENCE;
DROP SEQUENCE IF EXISTS ENTITY_SEQUENCE;
DROP TABLE IF EXISTS PROVIDED_ID_ENTITY;

CREATE TABLE dummy_entity
(
Expand Down Expand Up @@ -55,4 +56,10 @@ CREATE TABLE ENTITY_WITH_SEQUENCE
NAME VARCHAR(100)
);

CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

CREATE TABLE PROVIDED_ID_ENTITY
(
ID BIGINT PRIMARY KEY,
NAME VARCHAR(30)
);
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ CREATE TABLE WITH_DELIMITED_COLUMN
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
`ORG.XTUNIT.IDENTIFIER` VARCHAR(100),
STYPE VARCHAR(100)
);
);

CREATE TABLE PROVIDED_ID_ENTITY
(
ID BIGINT PRIMARY KEY,
NAME VARCHAR(30)
);
Loading
Loading