У меня проблема с поведением того, как работает весенняя транзакция. Мне не ясно, как правильно это реализовать. Эта проблема возникает, только если я включаю зависимость spring-session-jdbc
.
- Я использую Spring Boot 2.2.6
- с Hibernate / Mariadb
- Spring security включен с
InMemoryUserDetailsManager
У меня есть метод, который аннотируется как @Transactional(readonly=true)
и возвращает коллекцию сущностей. После получения коллекции от этого метода перед отправкой я установил для некоторых переменных разные значения, чтобы они не отображались или не меняли представление. Проблема в том, что после отправки вывода значения базы данных автоматически обновляются .
Чтобы подвести итог, я создал базовый проект c SpringBoot 2.2.6, ниже приводится его содержание.
Заказчик. java
@Data
@Entity
@Table(name = "customers")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer age;
private Integer batch;
private String secret;
}
CustomerRepository. java
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
Page<Customer> findByBatch(Integer batchId, Pageable pagaable);
}
CustomerService. java Следует отметить, что в этом классе обслуживания метод аннотирован с @Transactional(readOnly = true)
.
@Service
public class CustomerService {
@Autowired
private CustomerRepository repo;
@Transactional(readOnly = true)
public Page<Customer> findAllCustomers() {
Pageable pageable = PageRequest.of(0, 10);
return repo.findByBatch(4, pageable);
}
}
CustController. java
@Controller
public class CustController {
@Autowired
private CustomerService service;
@GetMapping("/")
public ResponseEntity<Page<Customer>> indexPath(Model model) {
Page<Customer> customers = this.service.findAllCustomers();
model.addAttribute("customers", customers);
// setting null before sending to client
// this is for demonstration purpose only
customers.getContent().forEach(i -> i.setSecret(null));
return ResponseEntity.ok(customers);
}
}
Зависимости в пом. xml
- spring-boot-starter-data-jpa
- spring-boot-starter-thymeleaf
- spring-boot-starter-web
- spring-boot -starter-security
- mariadb- java -клиент
- ломбок
- spring-session-jdb c
и заполнять база данных ниже содержит несколько SQL операторов вставки.
CREATE TABLE IF NOT EXISTS `customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`age` int(11) DEFAULT NULL,
`batch` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`secret` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM; // changed to InnoDB basedon @M.Deinum comment
INSERT INTO `customers` (`id`, `age`, `batch`, `name`, `secret`) VALUES (1, 94, 4, 'Ravi', '23423424234');
INSERT INTO `customers` (`id`, `age`, `batch`, `name`, `secret`) VALUES (2, 32, 4, 'Silva', '3424252432');
INSERT INTO `customers` (`id`, `age`, `batch`, `name`, `secret`) VALUES (3, 18, 4, 'Rahul', '322342424');
Пример проекта в Github
Я создал этот простой проект, который воспроизводит проблему, и загрузил это в Github в этом URL https://github.com/imuneer/sprintboot-db-issue.
* 10 72 * Просто закомментировав
spring-session-jdbc
в пом. xml, вы заставите проект работать как положено; никакое значение, которое я обновляю в моем контроллере, не изменяет фактические значения базы данных. Но когда
spring-session-jdbc
не прокомментирован, он работает наоборот.
Я запутался здесь.
- Почему добавление
spring-session-jdbc
меняет поведение весенней транзакции - Я что-то пропустил, так что программа ведет себя по-разному в обоих сценариях ios?
- Или мое понимание неверно? Если да, то как правильно отсоединить коллекцию от контекста сохранности перед ее изменением на клиенте.