Home > Blockchain >  Exclude fields from Java object using Spring
Exclude fields from Java object using Spring

Time:07-09

@PostMapping("/searchCarBigList")
public ResponseEntity<Cars> searchBigList(
        @Parameter(description = "some searchRequest dto") @RequestBody SearchRequest searchRequest) {

    return ResponseEntity.ok(someService.search(searchRequest));
}


@PostMapping("/searchCarSmallList")
public ResponseEntity<Cars> searchSmallList(
        @Parameter(description = "some searchRequest dto") @RequestBody SearchRequest searchRequest) {

    return ResponseEntity.ok(someService.search(searchRequest));
}




@Table(name = "CAR_TABLE")
public class Cars {

    @Id
    @Column(name = "ID")
    private Long id;

    @Column(name = "BRAND", nullable = false)
    private String brand;

    @Column(name = "COUNTRY", nullable = false)
    private String country;

    @Column(name = "CLIENT", nullable = false)
    private String client;

    @Column(name = "TRANSMISSION", nullable = false)
    private String transmission;
    
    
    Getters and Setters
}

I have two endpoint who use the same model class (Cars). For the searchBigList endpoint I would like to retrieve all car fields and for searchCarSmallList endpoint I would like to retrieve just 3 fields. I tried to do it with @JsonView annotation but it was not working for me. Anyone have better idea how to do it?

CodePudding user response:

It is a BAD idea to use JPA entities as DTOs, as once you get into any more complex schema you will be plagued with issues related to detached entities and lazy evaluation, etc.

Your controller should only deal with separate DTO class objects which have the desired properties, which you can then build to look like whatever you want. The service layer interface should only mention these DTOs, not Entity classes.

Only the repository layer should be written in terms of Entity classes, so the service layer should translate between DTO and Entity (accept and return DTO, pass Entity to the repo layer).

In the end this will save you a huge amount of time and pain on any real world type of project. There are plenty of tools and idioms for dealing with the DTO<->Entity conversions, and you may even choose to go with something like JsonObject for your DTOs if you don't require any sort of additional logic in them.

CodePudding user response:

You can have one Car model class which only has 3 essential fields. This object can be used for any web-service which requires only these 3 fields.

In your case, searchCarSmallList endpoint.

Extend Car model class & create another class which has additional 2 fields. In this new class, you can access Car class's fields.

Access this new class in another endpoint which needs all 5 fields.

If above approach is not possible, then use

BeanUtils.copyProperties, where you can explicitly mention field names which you want to ignore before display / return.

CodePudding user response:

I fully agree with Tod Harter that it's better and easier to use DTOs.

That being said, I don't know how you've tried to use the @JSonView annotation. I use it in some of my DTOs. One way of getting the @JsonView annotation to work is to first create an interface. i.e.:

public interface Views {
    public static interface Simple {
    }

    public static interface Detailed extends Simple {
    }

    ...
}

Then you need to reference the views above the fields that you want to apply them to like this:

@JsonView(Views.Simple.class)
private String someField;

@JsonView(Views.Detailed.class)
private String anotherField;

...

After that you need to convert your entity object to a MappingJacksonValue like this:

...
var responseObject = new MappingJacksonValue(obj);
responseObject.setSerializationView(Views.Simple.class);
...

This is one of the ways to make the @JsonView annotations work as expected. however, it is much easier (and better) to just use DTOs and convert your entity to the appropriate response DTO you've created. You can make as many DTOs as you want. It's also a good idea to use DTOs to map request bodies. That way you can easily control which fields are allowed in request bodies for i.e. POST/PUT/PATCH requests. Take a look at the ModelMapper and/or ObjectMapper classes. Those can be used to convert entities to and from DTOs.

  • Related