How to populate DTO class string fields using JPA

2019-02-25 18:29发布

问题:

I'm using JPA Criteria API, and in my query multiselect I want to retrieve an enum attribute, and not the enum itself.

This is my query :

final CriteriaQuery<MyClassDTO> query = builder.createQuery(MyClassDTO.class);

in MyClassDTO I have 4 fields as following:

private String icon;
private String provenance;
private int sizeX;
private int sizeY;

And the path I'm retrieving data from is :

final Root<MyClass> from = query.from(MyClass.class);

MyClass has 3 fields :

@Column
@Enumerated(EnumType.STRING)
private EnumTileIcon enumTileIcon;

@Column
@Enumerated(EnumType.STRING)
private EnumProvenance enumProvenance;

@Column
@Enumerated(EnumType.STRING)
private EnumSize enumSize;

What I want to do is to populate the MyClassDTO using the query.multiselect, something like this :

query.multiselect(
    from.get(MyClass_.enumTileIcon.toString()),
    from.get(MyClass_.enumProvenance.name()),
    from.get(MyClass_.enumSize.getWidth()),
    from.get(MyClass_.enumSize.getHeight())
);

How can I solve this ?

回答1:

I am not sure about the role of multiselect. But when dealing with projections what this seems to be you can use CriteriaBuilder.construct()

Create constructor to MyClassDTO like (add params if needed)

public MyClassDTO(EnumTileIcon icon, EnumProvenance provenance) {
    this.icon=icon.toString();
    this.provenance=provenance.toString();
}

Call the constructor in query like (add get params to match constructor params if needed)

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyClassDTO> cq = cb.createQuery(MyClassDTO.class);
Root<MyClass> root = cq.from(MyClass.class);
cq.select(cb.construct(MyClassDTO.class,
             root.get("enumTileIcon"), root.get("enumProvenance")));

Then you will be able to get

TypedQuery<MyClassDTO> tq = em.createQuery(cq);