Spring Boot: Wyłącz programowe pobieranie PersistentBag

Nov 13 2020

Mam jednostkę w Spring Boot, która wygląda tak:

@Entity
@Table(name = "race_class")
@Getter @Setter
public class RaceClass
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer dbid;

    private String name;

    private String colorHexcode;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "raceClass", cascade = CascadeType.ALL)
    private List<Entry> entries;
}

W swojej usłudze mam już jedną metodę, która dodatkowo pobiera wszystkie wpisy klasy raceclass. Co wygląda tak:

public List<RaceClassDto> getClassesEntries( int eventDbid )
{
    return this.raceClassRepo.findByEventDbid( eventDbid )
        .stream()
        .map( c -> addEntriesToRaceClass( eventDbid, c ) )
        .map( raceClassMapper :: mapToDto )
        .collect( Collectors.toList() );
}

Mapper wygląda tak:

public RaceClassDto mapToDto( RaceClass raceClass )
{
    return modelMapper.map ( raceClass, RaceClassDto.class );
}

Teraz chcę mieć drugą metodę, która nie pobiera wpisów automatycznie. Ale właśnie tutaj jest mój problem. Nowa metoda wyglądałaby następująco:

public List<RaceClassDto> getClasses( int eventDbid )
{
    return this.raceClassRepo.findByEventDbid( eventDbid )
            .stream()
            .map( raceClassMapper :: mapToDto )
            .collect( Collectors.toList() );
}

Jednak wpisy zostaną mimo to pobrane, ponieważ getEntries () zostanie wywołana w DTO-Mapper, który automatycznie wykonuje zapytania wybierające i wypełnia kontener wpisów. Jak można programowo wyłączyć automatyczną synchronizację PersistentBag tylko dla metody getClassesEntries ()?

Odpowiedzi

1 jccampanero Nov 13 2020 at 20:50

Myślę, że nie można programowo wyłączyć rozwiązywania relacji.

Lepszym podejściem będzie zdefiniowanie nowej metody w programie mapującym, nadanie jej nazwy mapToDTOWithoutResolvingEntriesi nie rozwiązywanie relacji w tej metodzie.

Za komentarze, jeśli używasz ModelMapper, w przypadku konkretnego zastosowania, może można pominąć na entrieswłasność swojej DTO.

Spróbuj czegoś takiego:

public RaceClassDto mapToDTOWithoutResolvingEntries( RaceClass raceClass) {
    return modelMapperWithoutResolvingEntries
      .map ( raceClass, RaceClassDto.class );
}

Gdzie modelMapperWithoutResolvingEntriesjest to samo, modelMapperco zdefiniowałeś wcześniej, mappingdodając:

ModelMapper modelMapperWithoutResolvingEntries = new ModelMapper();
modelMapperWithoutResolvingEntries
    .addMappings(mapper -> mapper.skip(RaceClassDto::setEntries));

Możesz TypeMapzamiast tego użyć create a, powinno zachowywać się tak samo.

Masz inne alternatywy. Na przykład możesz podać własne PropertyMap(zapoznaj się z odpowiednim javadoc i jak nadpisują configuremetodę), a może nawet plik Converter.

1 MAnouti Nov 13 2020 at 20:50

Wydaje mi się, że modelMapperpochodzi z biblioteki ModelMapper , więc w tym przypadku możesz powiedzieć jej, aby pominęła mapowanie wpisów, zgodnie z tym pytaniem .

W przeciwnym razie prawdopodobnie możesz skopiować dane z załadowanego obiektu JPA do innego obiektu, z wyłączeniem tych leniwie pobieranych danych.