4

I want to query the list of the phone with the person as a phone DTO object but while I construct a DTO object it provides an error.

Phone Entity:

public class Phone {

    @Id
    @GeneratedValue
    private Long id;

    private String number;

    @Enumerated(EnumType.STRING)
    private PhoneType type;

    @ManyToOne
    @JoinColumn(name = "person_id")
    private Person person;

}

Person Entity:

public class Person {

    @Id
    @GeneratedValue
    private long id;

    private String name;

    private String nickName;

    private String address;

    private LocalDateTime createdAt;

    @Version
    private int version;

    @OneToMany(mappedBy = "person" cascade = CascadeType.ALL)
    private List<Phone> phones;
}

Phone DTO:

public class PhoneDTO {

    private Long id;

    private String number;

    private PhoneType type;

    private PersonDTO person;

}

Person DTO:

public class PersonDTO {

    private long id;

    private String name;

    private String nickName;

    private String address;

    private LocalDateTime createdAt;

    private int version;

}

Criteria query:

CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<PhoneDTO> criteriaQuery = builder.createQuery(PhoneDTO.class);
        Root<Phone> root = criteriaQuery.from(Phone.class);
        Join<Phone, Person> person = root.join("person");

        Path<Object> id = root.get("id");
        Path<Object> number = root.get("number");
        Path<Object> type = root.get("type");

        Path<Object> personId = person.get("id");
        Path<Object> name = person.get("name");
        Path<Object> nickName = person.get("nickName");
        Path<Object> address = person.get("address");
        Path<Object> createdAt = person.get("createdAt");
        Path<Object> version = person.get("version");

        criteriaQuery.select(builder.construct(PhoneDTO.class, id, number, type, builder.construct(PersonDTO.class, personId, name, nickName, address, createdAt, version)));

        TypedQuery<PhoneDTO> query = em.createQuery(criteriaQuery);

How to do this??

criteriaQuery.select(builder.construct(PhoneDTO.class, id, number, type, builder.construct(PersonMediumDTO.class, personId, name, nickName, address, createdAt, version)));

How to construct a nested object??

Md. Shamim
  • 41
  • 1
  • 3
  • Note that since JPA 2.0 you don't need DTO objects, just use `Entity` classes. You should build your queries simply returning `Phone` and `Person` classes. For doing that with JPA Criteria, you don't need to use CriteriaBuilder.construct, simply select your Phone root as shown on page 1 of any Hello World JPA (or JPA Criteria API) tutorial – perissf Jun 03 '20 at 10:40
  • If I want to select some specific column from both tables and construct a nested object then how would be code? – Md. Shamim Jun 04 '20 at 14:26
  • In that case your approach should work, which error do you get exactly and using which of the 2 select methods you posted? Another approach is using tuples https://stackoverflow.com/a/12702437/870122 – perissf Jun 04 '20 at 14:54
  • Also, avoid using `Object` everywhere. Instead use MetaModel API or specify the correct object like `Path name = person. get("name");` – perissf Jun 04 '20 at 15:04
  • If I generate a flat object it's quite easy to do with Path but Nested object generate I didn't get how? Is that approach right what I wrote above? And if I use Tuple it could be a solution but for this is need to write a loop generate an object that actually I want to skip. – Md. Shamim Jun 04 '20 at 16:59
  • 1
    I need exactly the same, I've a nested DTO and I tried to use a construct inside another but throws an error _antlr.NoViableAltException: unexpected token: ,_ – Hector Jun 23 '20 at 20:28

0 Answers0