Usuwanie elementów z listy mapowanej encji w klasie z adnotacją @Transactional

0

Mam klasę oznaczoną adnotacją @Transactional

@Transactional
public class ContributionPersistenceServiceImpl implements ContributionPersistenceService

W tej klasie mam metodę do aktualizacji kontrybucji. Pobieram to encję.

final ContributionEntity contributionEntity = this.findContribution(contributionId, EditStatus.WAITING, user, MovieField.OTHER_TITLE);

Ta encja

ContributionEntity 

mapuje encje filmu

    @ManyToOne
    private MovieEntity movie;

która natomiast mapuję listę tytułów

    @OneToMany(mappedBy = "movie", cascade = CascadeType.ALL)
    private List<MovieOtherTitle> otherTitles;

Użytkownik podczas aktualizacji kontrybucji mógł wysłać listę elemntów inną niż podczas tworzenia tej kontrybucji, więc jeśli nie ma danego elemntu w przysłanej kontrybucji DTO to chcę usunąć ją z listy tytułów filmu(czyli z bazy). Na początku contributionEntity ma na liście dodany elementów element z ID 5001 https://zapodaj.net/3f34a1e36e6e2.png.html. Tak samo film ma dodany tytuł o id 5001 https://zapodaj.net/fb613b1bcac02.png.html.

this.cleanUpIdsToAdd(contributionEntity.getIdsToAdd(), contribution.getElementsToAdd().keySet(), contributionEntity.getMovie().getOtherTitles());

private void cleanUpIdsToAdd(final List<Long> idsToAddFromEntity, final Set<Long> idsToAddFromDto,
                             final List<? extends MovieInfo> entites) {
    for (final Iterator<Long> it = idsToAddFromEntity.iterator(); it.hasNext(); ) {
        final Long id = it.next();
        if (!idsToAddFromDto.contains(id)) {
            it.remove();
            entites.removeIf(movieInfo -> movieInfo.getId().equals(id));
        }
    }
}

Czyli jeśli element jest w liście tytułów filmu z bazy, a nie ma go w przysłanym DTO, to kasuję go z bazy, czyli z listy tytułów encji. Encja filmu jest pobierana z encji kontrybucji. Program na bieżącą debuguję i widzę, że element został poprawnie usunięty z listy idsToAdd kontrybucji i z listy otherTitle filmu. Powyższa metoda usunęła z contributionEntity z listy ID do dodania element o id 5001 https://zapodaj.net/9bf5fa23dc456.png.html. Tak samo element o ID 5001 został usunięty z listy tytułów filmu https://zapodaj.net/6341d9e447b5f.png.html. Teraz poprzedni tytuł jest ostatni.Teraz chcę dodać do listy tytułów filmu nowy tytuł

  contribution.getNewElementsToAdd()
                .forEach(otherTitle -> {
                    final Long id = this.moviePersistenceService.createOtherTitle(otherTitle, contributionEntity.getMovie(), user);
                    contributionEntity.getIdsToAdd().add(id);
                });
...  // metoda createOtherTitle jest w innej klasie
    @Override
    public Long createOtherTitle(
            @NotNull @Valid final OtherTitle otherTitle,
            @NotNull final MovieEntity movie,
            @NotNull final UserEntity user
    ) {
        final MovieOtherTitle movieOtherTitle = new MovieOtherTitle(otherTitle.getTitle(), otherTitle.getCountry());
        movieOtherTitle.set...
        ...

        movie.getOtherTitles().add(movieOtherTitle);

        this.movieRepository.save(movie);

        return Iterables.getLast(movie.getOtherTitles()).getId();
    }

Tytuł został dodany do listy tytułów filmu https://zapodaj.net/1849857a351b0.png.html. Widzimy, że element z title = test_app nie ma na liście.
Nowy tytuł w metodzie createOtherTitle jest dodawany do listy tytułów filmu i zapisywany do bazy. Dodam tutaj, że na tej liście tytułów nie ma usuniętych tytułów metodą cleanUpIdsToAdd. Zaraz po tym sprawdzam bazę, a tu niespodzianka. Są zapsiane w bazie nowe obiekty nowego tytułu dla filmu, ale elementy które zostały usunięty z listy tytułów filmu są nadal w bazie, nie zostały usunięte. Nie wiem dlaczego. (więcej kodu https://pastebin.com/d6bGxf1F) Screen z bazy https://zapodaj.net/38eb00f72e4d4.png.html. Jest zapisany nowy element tytuł, ale również jest element usunięty z ID 5001.

Fragment

entites.removeIf(movieInfo -> movieInfo.getId().equals(id));

usuwa z listy poprawnie tytuły podczas trwania metody(podczas debugowania sprawdzam to). Ale po zakończeniu metody okazuje się, że tytuły były usuwane tylko podczas działania metody, ale po zakończonej metodzie, gdy EclipseLink wykonuje automatycznie wygenerowane polecenie, to nie usuwa tytułu z bazy.

1

@OneToMany(mappedBy="movie", orphanRemoval=true, cascade=CascadeType.ALL)

1 użytkowników online, w tym zalogowanych: 0, gości: 1