In the project I´m working there is a part of the database that is like the following diagram
The domain classes have a definition similar to the following:
class File{
String name
}
class Document{
File file
}
class LogEntry{
Document document
Date date
}
First I need to get only the latest LogEntry for all Documents; in SQL I do the following (SQL_1):
SELECT t1.* FROM log_entry AS t1
LEFT OUTER JOIN log_entry t2
on t1.document_id = t2.document_id AND t1.date < t2.date
WHERE t2.date IS NULL
Then in my service I have a function like this:
List<LogEntry> logs(){
LogEntry.withSession {Session session ->
def query = session.createSQLQuery(
"""SELECT t1.* FROM log_entry AS t1
LEFT OUTER JOIN log_entry t2
on t1.document_id = t2.document_id AND t1.date < t2.date
WHERE t2.date IS NULL"""
)
def results = query.with {
addEntity(LogEntry)
list()
}
return results
}
}
The SQL query does solve my problem, at least in a way. I need to also paginate, filter and sort my results as well as join the tables LogEntry, Document and File. Altough it is doable in SQL it might get complicated quite quickly.
In other project I´ve used criteriaQuery similar to the following:
Criteria criteria = LogEntry.createCriteria()
criteria.list(params){ //Max, Offset, Sort, Order
fetchMode 'document', FetchMode.JOIN //THE JOIN PART
fetchMode 'document.file', FetchMode.JOIN //THE JOIN PART
createAlias("document","_document") //Alias could be an option but I would need to add transients, since it seems to need an association path, and even then I am not so sure
if(params.filter){ //Filters
if(params.filter.name){
eq('name', filter.name)
}
}
}
In these kinds of criteria I´ve been able to add custom filters, etc. But I have no Idea how to translate my query(SQL_1) into a criteria. Is there a way to accomplish this with criteriaBuilders or should I stick to sql?