Home > front end >  aggregation (count, sum) and grouping in Spring Data Jpa Specification
aggregation (count, sum) and grouping in Spring Data Jpa Specification

Time:10-04

He guys, I'm new one in Java, and i little bit stuck. If it possible to get person like map<Status, Integer> using Specification? I have classes Person and Status, and my business to make endpoint that return those map by filters (sex, age) how works filters i've already understood, but how not using @Query to get map - not. Below my classes:

@Entity(name = "persons")
@Getter
@Setter
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private String id;
    private String name;
    private int age;
    private String sex;
    private Status status;
}

@Getter
public enum Status {
    ONLINE,
    OFFLINE,
    BANNED,
    DELETED;
}

my endpoint must return { ONLINE: 5, OFFLINE: 17, BANNED: 2, DELETED: 4 }

CodePudding user response:

I believe you are looking for Projections: https://www.baeldung.com/spring-data-jpa-projections

Spring data allows you to do what you ask for using an interface without providing an implementation which is very convenient!

Suppose you have an entity car:

@Entity
public class Car {
 
    @Id
    private Long id;
 
    private String model;
 
    private String color;
 
    private int year

    // getters and setters
}

And you want to retrieve the color and year. You can do so with an interface:

public interface ICarProjection {
    String getColor();
    int getYear();
}

Make sure the naming of your methods in the interface are identical to that of your entity, this is important.

In your repository you can now use the interface in place of the full entity:

public interface CarRepository extends Repository<Car, Long> {
    @Query('xxx')
    List<ICarProjection> getColorAndYear();
}

CodePudding user response:

Yes you can get map collection on entity but only when you join two tablet using @ElementCollection for example.

@Entity
public class Store {
  @Id
  protected long id;
 
  @ElementCollection
  @CollectionTable(name = "item_quantity",
        joinColumns = { @JoinColumn(name = "store_id") })
  @MapKeyColumn(name = "item")
  @Column(name = "quantity")
  protected Map<String, Integer> itemQuantityMap = new HashMap<>();

In your case better way is mapping result lists by stream.

List<Person> result = repository.findAll();
var map = result.stream().collect(Collectors.toMap(Person::getStatus, Person ::getSex))
  • Related