I've got a Java application that, among other things, goes out to our Active Directory server every hour, and pulls down a list of all the accounts, and dumps them in a database; this work is done via a thread that's spawned new every hour, and the database interfacing is done via Hibernate. The thread's run method (essentially the only thing this thread does) looks like so:
public void run() {
try {
Thread.sleep(3600000); //we run once an hour, so we sleep for an hour
Thread newHourlyRunThread = new Thread(new HourlyRunThread());
newHourlyRunThread.start();
LDAPNewUsersReport report = new LDAPNewUsersReport();
Calendar calendar = Calendar.getInstance();
calendar.set(0, 0, 0, 0, 0); //We tell the report to look for everything from 12AM Jan 1 0 AD, which should be sufficient to find all created AD objects.
report.runReport(calendar.getTime(), new Date());
HashSet<LDAPEntry> allEntries = report.getAllEntries();
Iterator it = allEntries.iterator();
while (it.hasNext()) {
ContactParser.parseContact((LDAPEntry) it.next());
}
}
The relevant methods from ContactParser are below:
public static void parseContact(LDAPEntry entry) {
Contact chosenContact = null;
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List contacts = session.getNamedQuery("ContactByCanonicalName").setString(0, entry.getDN()).list();
Iterator it = contacts.iterator();
if (it.hasNext()) {
chosenContact = (Contact) it.next();
chosenContact = ContactParser.fillContactFields(chosenContact, entry);
} else {
chosenContact = ContactParser.fillContactFields(new Contact(), entry);
}
session.saveOrUpdate(chosenContact);
session.getTransaction().commit();
}
private static Contact fillContactFields(Contact chosenContact, LDAPEntry entry) {
chosenContact.setCanonicalName(entry.getDN());
chosenContact.setFirstName(ContactParser.getEntryField(entry, "givenName"));
chosenContact.setLastName(ContactParser.getEntryField(entry, "sn"));
chosenContact.setUserName(ContactParser.getEntryField(entry, "sAMAccountname"));
chosenContact.setEmployeeID(ContactParser.getEntryField(entry, "employeeID"));
chosenContact.setMiddleName(ContactParser.getEntryField(entry, "initials"));
chosenContact.setEmail(ContactParser.getEntryField(entry, "mail"));
if(chosenContact.getFirstSeen() == null){
chosenContact.setFirstSeen(new Date());
}
chosenContact.setLastSeen(new Date());
return chosenContact;
}
private static String getEntryField(LDAPEntry entry, String fieldName){
String returnString = "";
if(entry.getAttribute(fieldName) != null){
returnString = entry.getAttribute(fieldName).getStringValue();
}
return returnString;
}
This all works very nicely if we're only running a single instance (so, no new threads are spawned after the fact), but if we run this thread more than once (IE, I speed up execution to ~30 seconds so that I can see issues), Hibernate is reporting a lack of Heap space. This doesn't seem like it's a particularly intense set of data (only about 6K entries), but I'm seeing that same error when we bump the code over to the staging error to prepare to push to production. I'm inexperienced when it comes to writing effective threads, and very inexperienced when it comes to Hibernate, so if anyone has an idea what might be exhausting our Heap space (the other major thread in this application isn't running at the same time, and takes up a few hundred kilobytes of memory total) from looking at the code, I'd greatly appreciate any suggestions.
Thanks in advance.