views:

33

answers:

1

I have a rather big model Applicant:

public class Applicant{
 private Long id
 private String name;
 ...
 ...
}

To populate a selection list, I need a list of (id, name) tuples and I use this search query:

public List getNames() {
    Query query = em.createQuery("select a.id, a.name from Applicant a");
    return query.getResultList();

}

However, I get a list of Object[]'s and I don't really want to convert these in the business layer to the corresponding types (Long and String). What is the best way to approach this? Should I iterate through the list and manually do the type conversion before returning it? Or should I make a helper class:

public class ApplicantTuple{
 public Long id
 public String name;

 public Application(Long id, String name) {
    ...
 }

}

and then have a search query:

Query query = em.createQuery("select NEW my.model.ApplicantTuple(a.id, a.name) from Applicant a");

Or is there a better way to type search queries?

+1  A: 

Since you're apparently using JPA2, use the type-safe methods:

public List<Applicant> getApplicants() {
    TypedQuery<Applicant> query = em.createQuery(
        "select a.id, a.name from Applicant a",
        Applicant.class
    );
    return query.getResultList();
}

Then just use the Objects:

for(Applicant app: getApplicants()){
    selectionList.populate(app.getName(), app.getId());
}
seanizer
What happens with the other fields of the Applicant object? They don't get fetched? And is this possible when I use join and query for fields from two tables/entities?
John Manak
Yes, the other fields do get fetched, unless they are configured as lazy.
seanizer
However that makes the result set unnecessarily bulky, doesn't it?
John Manak
That's the tradeoff if you use an object-oriented approach on top of a relational database. In an ORM, you are dealing with objects (and hence you have overhead). That's the price you have to pay for type safety and ease of programming. If you don't want to pay this price, use JDBC or IBatis.
seanizer
One more note: if `Applicant` is huge, try to move some of it's non-frequently needed data to associated classes / tables, e.g. let it have an `Address` field with a `@OneToOne` relationship that's defined as lazy etc. Huge Classes are another indication that you are not going the object oriented way and hence may be better off using plain JDBC (or building a real object hierarchy).
seanizer
Ok, that makes sense. But then there's no difference between "select a.id, a.name from Applicant a" and "select a from Applicant a", right?
John Manak
yes there is: the former returns meaningful objects (Applicant) the second returns arrays of objects you have to check and cast first)
seanizer
I mean the case when I use typed queries:TypedQuery<Applicant> query = em.createQuery("select a.id, a.name from Applicant a", Applicant.class);In this case, there's no difference as far as I understand it.
John Manak
I am pretty sure that query will generate a ClassCastException or something similarly ugly.
seanizer