At first I am sorry for bad English, it's not my mother tongue. But I will try my best...
Basic things...
Hibernate version: 3.0.5
Using: the Criteria API (very important, because I generate the queries dynamically!)
Database: a Lotus Domino database (connected through a dominoJDBC driver)
Hi! =)
I already worked with Hibernate, but I think I am still new to it anyway. So I searched for the answer of my question in the tutorial and in this forum. But unfortunately I could'nt find any helping topic.
So I ask you.
To avoid misunderstandings:
I already have another solution, but it takes too long. That's why I ask my question anyhow.
In short: I'd like to know, how to create and configure a Criteria which represents some kind of INNER JOIN between two tables/views.
In long: There is a database table called "Ticket" (by the way: I work with the database of a Trouble Ticket System; it's not common, it is developed and used in the company I am working for). The data in the table represents trouble tickets. These trouble tickets are historized by adding new datasets to the table.
So if there is a change of a trouble ticket's attributes a new ticket will be inserted into the table instead of updating the dataset. That is done by
a Lotus Notes frontend. So that's not my problem yet.
I "only" want to (have to) read the data with a Java application. That ain't no problem. I only append some dynamically generated Criterions to a Criteria and get my tickets.
BUT: I also get every historized version of a trouble ticket. The big problem is, that I can't differ between the old versions and the latest version of a ticket (that is internally managed by the Lotus Domino database). Even the unique identifier "NoteID" (generated by the database) can't help, because it is not consecutively numbered.
However, I got some kind of solution: There is a detour.
The database offers a view that only determines the latest trouble tickets.
The 2nd BUT: From that view I don't get all the attributes of a trouble ticket I need.
So I did the following in my application: With help of the Hibernate Criteria API I ask the "Ticket" table for all trouble tickets I want to have. Here I get -as I said- the latest and the older versions of the datasets. Afterwards I filter the old tickets out by iterating every ticket (old and new) and comparing the NoteID with the NoteIDs I get from the view (as I said, in that view only the latest versions are fetched). Therefor I introduced a dummy.
In the follwing you can see an extract of my hibernate-mapping-xml's:
Code:
<!-- troubleticket.hbm.xml -->
<hibernate-mapping>
<class name="my.package.TroubleTicket" table="Ticket">
<id name="noteId" column="NoteID"></id>
<property name="ticketnummer" column="ticketnr"/>
<property name="status" column="status"/>
<!-- etc. ... -->
</class>
<hibernate-mapping>
Code:
<!-- troubleticketdummy.hbm.xml -->
<hibernate-mapping>
<class name="my.package.TroubleTicketDummy" table="Alle_Tickets_ohne_Historien"> <!-- that is the view -->
<id name="noteId" column="NoteID"></id>
</class>
<hibernate-mapping>
Here you can see some Java code:
Code:
// Creating the Criteria
Criteria criteria = getSession().createCriteria(TroubleTicket.class);
// At this point I dynamically add the Criterions
// Imagine there is an Iterator called kritIterator, it returns some objects of class "Kriterium"
while (kritIterator.hasNext()) {
Kriterium kriterium = (Kriterium) kritIterator.next();
criteria.add(kriterium.getCriterion());
}
// the collection for ALL trouble tickets (old and new)
Collection troubleTickets = null;
try {
// getting all tickets
troubleTickets = criteria.list();
} catch (HibernateException e) {
// that's an own Exception, don't care about that
throw new TicketEyeException(e);
}
// the collection for the latest trouble tickets (without the historized versions)
Collection troubleTicketsUpToDate = new ArrayList();
// iterating all trouble tickets
// => that is what takes too much time (even with only about 100 tickets!)
Iterator troubleTicketsIterator = troubleTickets.iterator();
while (troubleTicketsIterator.hasNext()) {
TroubleTicket ticket = (TroubleTicket) troubleTicketsIterator.next();
Criteria criteriaHist = getSession().createCriteria(TroubleTicketDummy.class);
// add the comparison for the NoteID
criteriaHist.add(Restrictions.eq(TroubleTicket.PROPERTY_NOTEID, ticket.getNoteId()));
// if there is one, it is the latest version
if (!criteriaHist.list().isEmpty()) {
troubleTicketsUpToDate.add(ticket);
}
}
That works really fine. But it takes too long time! I would prefer to use something what is similar to the following SQL-code (only an example!):
Code:
SELECT * FROM Tickets t, ViewWithLatestTickets v
WHERE
t.NoteID = v.NoteID
AND
/* ... here the Criterions would be added ... */
Or something like the following SQL-code:
Code:
SELECT * FROM Tickets t
INNER JOIN ViewWithLatestTickets v
ON t.NoteID = v.NoteID
WHERE
/* ... here the Criterions would be added ... */
I hope you understand my request. Furthermore I hope this is possible to implement with the Criteria API.
Thanks a lot!
Best regards from Hamburg, Germany!
Arvid.
EDIT: Wow, my English really buggy... ;-) Next time I should order my thoughts and words first. But I won't try to correct my whole text now.