Spring Boot: программно отключить получение PersistentBag.

Nov 13 2020

У меня есть объект в Spring Boot, который выглядит так:

@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;
}

В моем сервисе уже есть один метод, который дополнительно извлекает все записи класса race. Что выглядит так:

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

Картограф выглядит так:

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

Теперь я хочу иметь второй метод, который не извлекает записи автоматически. Но именно в этом моя проблема. Новый метод будет выглядеть так:

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

Но записи все равно будут извлечены, потому что getEntries () будет вызываться в DTO-Mapper, который автоматически выполняет запросы выбора и заполняет контейнер записей. Как можно программно отключить автоматическую синхронизацию PersistentBag только для метода getClassesEntries ()?

Ответы

1 jccampanero Nov 13 2020 at 20:50

Я думаю, вы не можете программно отключить разрешение отношений.

Лучшим подходом будет определение нового метода в вашем картографе, назовите его mapToDTOWithoutResolvingEntriesи не разрешайте отношения в этом методе.

Для ваших комментариев, если вы используете ModelMapper, в вашем конкретном случае использования, может быть , вы можете пропустить в entriesсобственность вашего DTO.

Пожалуйста, попробуйте что-нибудь вроде следующего:

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

Где modelMapperWithoutResolvingEntriesто же, что modelMapperвы определили ранее, со следующим mappingдобавленным:

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

TypeMapВместо этого вы можете использовать create a , он должен вести себя так же.

У вас есть другие альтернативы. Например, вы можете предоставить свой собственный PropertyMap(см. Соответствующий javadoc и информацию о том, как они перезаписывают configureметод), или, может быть, даже Converter.

1 MAnouti Nov 13 2020 at 20:50

Я считаю, что modelMapperон исходит из библиотеки ModelMapper , поэтому в этом случае вы можете сказать ему, чтобы он пропустил сопоставление записей, как указано в этом вопросе .

В противном случае вы, вероятно, можете скопировать данные из загруженного объекта JPA в другой объект, исключая эти ленивые данные.