views:

381

answers:

2

Hi all,

I have the following beans Task, ServerDetails and ApplicationDetails. I wish to retrieve all tasks, their server details and application details based on a specific application name.

From the result i expect to be able to retrieve the data in a manner such as: task.getServers().getApplicationDetails()

In actuality, I get what seems to be flat data's representation as an Object[].

Is there any way to do what i propose?

Following is my code...

class Task {
    private String taskId;
    private Set<ServerDetails> servers;
}

class ServerDetails {
    private String id;
    private Set<ApplicationDetails> applications;
}

class ApplicationDetails {
   private String id;
}

HQL:

StringBuilder hql = new StringBuilder(256);
hql.append("FROM Task h, ServerDetails ser, ApplicationDetails app ");
hql.append("WHERE h.executionDate > "); 
hql.append("to_date('");
hql.append(DBDateFormatter.getInstance().formatDate(cal));
hql.append("',  '");
hql.append(DBDateFormatter.getInstance().getOracleDateFormat());
hql.append("') and h.id = ser.task.id and ser.id = app.server and app.name = 'XXX'");
hql.append(" order by h.executionDate desc");
String hql = hql.toString();

Query query = session.createQuery(hql);      
results = (List<Object[]>) query.list();
+3  A: 

You should just retrieve the main object.

For the other, you can:

  1. navigate to them while the Session has not be closed (runs additional queries as needed, known as lazy ; this is ideal for ease of use)
  2. retrieve them in the original query using the fetch keyword.

Example:

    SELECT h 
    FROM Task h
    JOIN FETCH h.serveurs ser
    JOIN FETCH ser.applications app 
    WHERE h.executionDate > 
    .... // no need to specify the joins

You will be able to retrieve the data in a manner such as:
task.getServers().getApplicationDetails()

KLE
thanks a lot for your help
Keren
+1. Three things to keep in mind here: (a) the above select should use **LEFT** join fetch unless you're 100% sure you always have servers / applications populated; (b) it may return duplicate `Task` instances so resulting list should be filtered (wrapped in Set, for example); and (c) using `to_date()` and formatting dates is completely unnecessary - specify it as parameter and set it on query as actual Date instead.
ChssPly76
Hi,I want to add to the hql something like that:hqlQ.append("LEFT JOIN FETCH h.prompts p on (h.id = p.task.id and p.applicationName in (" + apps.toString() + ")) "do you have idea how to do it?
Keren
@Keren Between 'h' and 'p', the relation seem to go through 'task', that would be easier. For the 'applicationName', it belongs to the 'where' part of the query.
KLE
A: 

You can retrieve the object graph as the others have said using LEFT JOIN FECH. One crevent I have found when retrieving object graphs, when walking down a many-to-one relationship you can not walk back up without additional database access.

James