2

I have a entity in Spring Boot which looks like that:

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

In my service I already have one method, which fetches all the entries of the raceclass additionally. Which looks like that:

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

The mapper looks like that:

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

Now, I want to have a second method, which doesn't fetch the entries automatically. But exactly here is my problem. The new method would look like this:

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

But the entries will be fetched nevertheless, because getEntries() will be called in the DTO-Mapper, which executes the select queries automatically and fills the entries container. How is it possible to programmatically disable the automatic synchronisation of the PersistentBag only for the getClassesEntries() method?

M A
  • 71,713
  • 13
  • 134
  • 174
user2622344
  • 956
  • 1
  • 10
  • 26

2 Answers2

1

I think you cannot programmatically disable the relationship resolution.

A better approach will be to define a new method in your mapper, name it mapToDTOWithoutResolvingEntries, and do not resolve the relationship in that method.

For your comments, if you are using ModelMapper, in your specific use case, maybe you can skip the entries property of your DTO.

Please, try something like the following:

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

Where modelMapperWithoutResolvingEntries is the same modelMapper you defined before with the following mapping added:

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

You can use create a TypeMap instead, it should behave the same.

You have other alternatives. For instance, you can provide your own PropertyMap (please, see the relevant javadoc and how they overwrite the configure method), or maybe even a Converter.

jccampanero
  • 50,989
  • 3
  • 20
  • 49
  • Do you know if there is any possibility in ModelMapper to add a mapping only in one particular method and not globally? – user2622344 Nov 13 '20 at 14:01
  • Sorry for the late reply. I updated my answer with further info. Please, let me know if you need further help. – jccampanero Nov 13 '20 at 17:32
1

I believe modelMapper is coming from the ModelMapper library, so in this case you could tell it to skip mapping the entries, as addressed in this question.

Otherwise, you can probably copy the data from the JPA loaded object into another object excluding those lazily fetched data.

M A
  • 71,713
  • 13
  • 134
  • 174