JDBC Spring data @Transactional не работает

#java #spring #spring-data

#java #весна #весна-данные

Вопрос:

Я использую springboot и spring-data-jdbc.

Я написал этот класс репозитория

 @Repository
@Transactional(rollbackFor = Exception.class)
public class RecordRepository {
    public RecordRepository() {}

    public void insert(Record record) throws Exception {
        JDBCConfig jdbcConfig = new JDBCConfig();
        SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(jdbcConfig.postgresDataSource());

        messageInsert.withTableName(record.tableName()).execute(record.content());
        throw new Exception();
    }
}
  

Затем я написал клиентский класс, который вызывает метод insert

 @EnableJdbcRepositories()
@Configuration
public class RecordClient {
    @Autowired
    private RecordRepository repository;

    public void insert(Record r) throws Exception {
        repository.insert(r);
    }
}
  

Я бы ожидал, что ни одна запись не будет вставлена в БД при RecordClient insert() вызове метода, RecordRespository потому insert() что он выдает Exception . Однако вместо этого добавляется запись.

Чего мне не хватает?

Редактировать. Это класс, в котором я настраиваю свой источник данных

 @Configuration
@EnableTransactionManagement
public class JDBCConfig {

    @Bean
    public DataSource postgresDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/db");
        dataSource.setUsername("postgres");
        dataSource.setPassword("root");

        return dataSource;
    }
}
  

Комментарии:

1. Были ли у вас аннотации @EnableTransactionManagement в вашем классе конфигурации?

2. Каков мой класс конфигурации? RecordClient или класс, в котором я настраиваю источник данных JDBC?

3. любой класс, который объявляет @Configuration . В вашем случае попробуйте добавить @EnableTransactionManagement в RecordClient или в класс, в котором вы настроили источник данных JDBC.

4. да, я добавил @EnableTransactionManagement в начало RecordClient класса, но результат тот же. Я пробовал также с моим классом JDBCConfig. См. Редактирование.

5. извините за поздний ответ, вы решили свою проблему?

Ответ №1:

Вы должны ввести свой datasource , а не создавать его вручную. Я думаю, потому @Transactional что работает только для Spring управляемых компонентов. Если вы создаете экземпляр источника данных, вызывая new конструктор (например, так new JDBCConfig(). postgresDataSource() ), вы создаете его вручную, и это не управляемые компоненты Spring.

 @Repository
@Transactional(rollbackFor = Exception.class)
public class RecordRepository {

  @Autowired
  DataSource dataSource;

  public RecordRepository() {}

  public void insert(Record record) throws Exception {
    SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(dataSource);
    messageInsert.withTableName(record.tableName()).execute(record.contents());
    throw new Exception();
  }
}