OptimisticLockingFailureException: пакетное обновление вернуло неожиданное количество строк - PullRequest
2 голосов
/ 29 мая 2019

У меня есть простое однонаправленное отношение Parent Child в моем приложении Spring Web MVC. У меня есть 2 RESTful API: POST & PUT.

Родительский субъект:

@Entity
@EqualsAndHashCode(exclude = {"children", "id"})
public class Parent {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "PARENT_ID", nullable = false, updatable = false)
    private Set<Child> children = new HashSet<>();
}

Дочерняя сущность:

@Entity
@EqualsAndHashCode(exclude = {"id"})
public class Child {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String name;
}

Контроллер:

@RestController
@RequestMapping("/parent")
public class Controller {

    @Autowired
    private ServiceImpl serviceImpl;

    @PostMapping
    public ResponseEntity<Parent> post(@RequestBody final Parent parent) {
        return new ResponseEntity<Parent>(serviceImpl.create(parent), HttpStatus.OK);
    }

    @PutMapping
    public ResponseEntity<Parent> put(@RequestBody final Parent parent) {
        return new ResponseEntity<Parent>(serviceImpl.update(parent), HttpStatus.OK);
    }
}

Уровень обслуживания:

@Service
public class ServiceImpl implements inter {
    @Autowired
    ParentRepository repository;

    public Parent create(Parent parent) {
        return repository.save(parent);
    }

    @Transactional(readOnly = true)
    public Parent findById(Long id) {
        return repository.findById(id).orElseThrow(IllegalArgumentException::new);
    }

    @Transactional
    public Parent update(Parent toUpdate) {
        Parent retrieved = this.findById(toUpdate.getId());

        retrieved.getChildren().retainAll(toUpdate.getChildren());
        retrieved.getChildren().addAll(toUpdate.getChildren());

        return repository.save(retrieved);
    }
}

У меня есть один репозиторий для родителей. Я создаю Родителя и детей вместе как часть API POST

Мне нужно обновить Parent и Children через PUT. Однако, когда я пытаюсь заменить одного или нескольких дочерних элементов уже созданного Parent, я получаю сообщение об ошибке:

{"timestamp":"2019-05-27T20:21:53.451+0000","status":500,"error":"Internal Server Error","message":"Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1","path":"/parent"}

Проблема возникает только при выполнении простого тестового теста JMETER с несколькими потоками.

Если я изменяю CascadeType на MERGE на родительской стороне отношений, тогда обновление работает, но сохранение новой сущности затем не удастся через Post api.

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