Данные Spring не увеличиваются после DBsetup - PullRequest
0 голосов
/ 03 сентября 2018

У меня такой вопрос. Я использую DBsetup для весенних загрузочных тестов и базы данных postgresql. И я использую DBsetup, чтобы установить пользователя, но когда я пытаюсь установить другого пользователя по данным весны, у меня есть следующее исключение:

Подробности: Key (id)=(1) already exists.

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [users_pkey];

Это мой тестовый класс:

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource("/application-test.properties")
public class UserRepositoryTest {

    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private DataSource dataSource;

    @Before
    public void insertData() throws SQLException {
        Operation operation = sequenceOf(CommonOperations.DELETE_ALL, CommonOperations.INSERT_USER);
        DbSetup dbSetup = new DbSetup(new DataSourceDestination(dataSource), operation);
        dbSetup.launch();
    }

    @After
    public void cleanPK() throws SQLException {
        DBUtil.resetAutoIncrementColumns(applicationContext, "user");
    }

    @Test
    public void registerUser() {
        val user = new User(null, "Glass", "123123", "glass999@mail.ru");
        assertEquals(user, userRepository.saveAndFlush(user));
    }

}

Операции для DBsetup:

public class CommonOperations {
    public static final Operation DELETE_ALL = deleteAllFrom("article_tag", "article", "tag", "users");
    public static final Operation INSERT_USER =
            insertInto("users")
                    .columns("id", "email", "password", "username")
                    .values(1, "krikkk998@mail.ru", "123123", "Daimon")
                    .build();
}

Класс для сброса последовательности:

@NoArgsConstructor
public final class DBUtil {

    public static void resetAutoIncrementColumns(ApplicationContext applicationContext,
                                                 String... tableNames) throws SQLException {
        DataSource dataSource = applicationContext.getBean(DataSource.class);
        String resetSqlTemplate = "ALTER SEQUENCE %s RESTART WITH 1;";
        try (Connection dbConnection = dataSource.getConnection()) {
            for (String resetSqlArgument: tableNames) {
                try (Statement statement = dbConnection.createStatement()) {
                    String resetSql = String.format(resetSqlTemplate, resetSqlArgument + "_id_seq");
                    statement.execute(resetSql);
                }
            }
        }
    }
}

Кто-нибудь знает, как решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

У вас есть проблема, связанная с нарушением ограничений. Поэтому вы можете изменить в своей таблице столбец 'id' на "auto_increment". БД позаботится об увеличении значения этого столбца автоматически.

В любой момент, если вы хотите сбросить это значение идентификатора, вы можете вызвать "resetAutoIncrementColumns()", и тогда в вашем INSERT SQL вам не нужно указывать столбец 'id' вообще. Он всегда будет вставлять уникальное значение при сохранении нового пользователя.

Надеюсь, это поможет вам.

0 голосов
/ 03 сентября 2018

На что посмотреть:

public static final Operation INSERT_USER =
        insertInto("users")
                .columns("id", "email", "password", "username")
                .values(1, "krikkk998@mail.ru", "123123", "Daimon")
                .build();

Здесь вы используете жестко идентифицированный идентификатор, т.е. 1

Теперь, когда в тестовом примере вы пытаетесь создать другого пользователя, вы передали идентификатор как ноль, предполагая, что он должен выбирать из последовательности. Это также начнется с 1. Следовательно, вы получите конфликт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...