Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AliasToBeanResultTransformer(MyDTO.class) fails to instantiate MyDTO

Tags:

hibernate

I would like a Criteria query to instantiate a DTO class using an AliasToBeanResultTransformer. The goal is to produce a light weight paged list with IDs for further action for a home page. This calls for a reporting type query.

            Criteria crit = session.createCriteria(Profile.class);

        crit.createAlias("personalData", "pd");
        crit.createAlias("emails", "e");
        crit.createAlias("telephones", "t");

        ProjectionList properties = Projections.projectionList();
        properties.add(Projections.property("id").as( "id"));
        properties.add(Projections.property("pd.lastName").as("lastName"));
        properties.add(Projections.property("pd.fullName").as("fullName"));
        properties.add(Projections.property("e.emailAddress").as("email"));
        properties.add(Projections.property("t.phoneNumber").as("phone"));

        crit.setProjection(properties);

        crit.setResultTransformer(new AliasToBeanResultTransformer(ProfileDTO.class));
        profiles = crit.list();

This fails to instantiate my DTO class. ProfileDTO has a matching constructor:

public ProfileDTO(Long id, String lastName, String fullName, String email,
        String phone) {
    this(id,fullName);
    this.lastName = lastName;
    this.email = email;
    this.phone = phone;
}

And the query works when I construct ProfileDTO objects manually with the result rows

        List<Object[]> rows = crit.list();

        for ( Object[] row: rows ) {
            ProfileDTO dto = new ProfileDTO();
            dto.setId((Long)row[0]);
            dto.setLastName((String)row[1]);
            dto.setFullName((String)row[2]);
            dto.setEmail((String)row[3]);
            dto.setPhone((String)row[4]);
            profiles.add(dto);
        }

My workaround is working fine, but it seems unnecessary. What am I doing wrong?

like image 331
carbontax Avatar asked Mar 07 '12 16:03

carbontax


1 Answers

The AliasToBeanResultTransformer uses setters to populate the DTO. If you want to use a constructor, to create your bean instance, you need to use an AliasToBeanConstructorResultTransformer.

Your DTO seems to have a setter for all the elements of the tuple, except for lastName. Maybe this is the problem.

That said, your code as is is simple, easy to maintain, and refactorable. It wouldn't be refactorable with an AliasToBeanResultTransformer. I generally prefer to instantiate my DTOs myself, just as you did.

like image 77
JB Nizet Avatar answered Nov 13 '22 18:11

JB Nizet