I'm developing an double-entry accounting system and I need to insert posting records without any gaps in the sequential id. Since all database access will happen through a web application, I'm taking care of id generation using a syncronized static variable:
import org.hibernate.*;
public class JournalService {
private static Object journalLock = new Object();
private Session session;
public JournalService(Session session) {
this.session = session;
}
public void insertJournalEntry(JournalEntry journalEntry) {
Set<PostEntry> entries = journalEntry.getEntries();
double total = 0;
for (PostEntry entry : entries) {
total += entry.getAmount();
}
if(total != 0)
throw new InvalidParameterException("Journal entry is invalid. The sum of all entries must be zero.");
Criteria criteria = session.createCriteria(PostEntry.class);
criteria.setMaxResults(1);
criteria.addOrder(Order.desc("id"));
//here I add some other criteria
synchronized(journalLock) {
PostEntry lastEntry = criteria.uniqueResult();
long currentId = lastEntry.getId();
for (PostEntry entry : entries) {
entry.setId(currentId++)
session.save(entry);
}
session.save(journalEntry);
}
}
}
In a few words, this service has a lifetime tied to the current httprequest and is managed by a spring container, besides I make sure the entire transaction is commited at the end of request. The syncronized block will take care of any concurrency so there's no way any gaps will happen in the id's sequence. The big problem here is the added overhead of database access for selecting the last inserted record that matches a certain criteria. I don't want that to happen so I'm guessing the solution here is using a cache that will hold the last inserted record the first time its selected, so no database access is needed for generating the id. My question : Is there any out-of-box hibernate way of solving this? I'm new to hibernate and heard about query cache's but I'm not sure on how to use it. I don't want the cache to hold every value I store using this service, I just need it to store the last inserted entry that matches a certain criteria. For example, if I perfomed five inserts, in which two matches a equal criteria 'X' and the other three matches a criteria 'Y', the cache will only have two objects stored(the last inserted object that matches each criteria). I could easily implement this myself, but I would rather use a solution that integrates with hibernate API.