Wednesday, December 10, 2008

Free Chapters!

Manning has made two chapters from the book available for free download (there isn't much available for free these days) from their MEAP program.
Chapter 2 entitled "Getting started with Hibernate Search" will give you an over-view of Hibernate Search: how to use it, how to express full-text queries, and how it fits into the Hibernate programmatic model.
Chapter 11 entitled "Accessing Lucene natively" starts with looking at Hibernate Search’s SearchFactory, which is the key entry point to Lucene. It also examines the effects that sharding presents, writing a custom DirectoryProvider and what you must take into account when you do.
We’ll also show you how to access the legacy Lucene document and several related values by utilizing a projection, and we’ll demonstrate how it affects performance.
Manning has also provided the book's source code for download from the same link.

Download them, sit back, do a little reading and see what you think.

Monday, December 1, 2008

Our Hibernate Search Refcard is out!


has just released our Refcard on Hibernate Search. This is a 6 page "cheatsheet" for new and experienced users of this technology filled with summary information for quick lookup. We hope you enjoy it and its makes life a little easier for you.

It looks like we will just make the December launch of Hibernate Search in Action. We're hoping to be on the shelves during the last week of December. It will make a great 'IOU one Christmas present' for that someone you know. It would also be a fantastic birthday present. Buy it, you'll like it!

Monday, October 13, 2008

Hibernate Session and Transaction Utilizing ThreadLocal Variables

At long last here is the post I promised that uses ThreadLocal variables to handle Hibernate sessions and transactions. The rather long helper class contains methods to obtain the current session (if one doesn't already exist it creates one), close the session, obtain a transaction, commit the transaction and rollback.
This is a good demonstration of the use of ThreadLocal variables and presents workable code that I hope you can use everyday. There is a lot more that can be added to this helper but that's a reader exercise.

public final class HibernateHelper
{
private static final ThreadLocal threadSession =
new ThreadLocal();
private static final ThreadLocal threadTransaction =
new ThreadLocal();
private static SessionFactory mSessionFactory;

static {
mSessionFactory = ServiceLocator.getInstance().getSessionFactory();
}

public static Session getCurrentSession() {
Session s = threadSession.get();
try {
if (s == null || !s.isOpen()) {
if (mLogger.isInfoEnabled()) {
mLogger.info("Opening new Session for this thread.");
}
s = mSessionFactory.openSession();
threadSession.set(s);
}
else {
if (mLogger.isInfoEnabled()) {
mLogger.info("Using current session in this thread.");
}
}
}
catch (HibernateException ex) {
throw ("unable to open hibernate session");
}
return s;
}

public static void closeSession() {
try {
final Session s = threadSession.get();
if (s != null && s.isOpen()) {
mLogger.info("Closing Session of this thread.");
s.close();
}
}
catch (HibernateException ex) {
Throw.loggable(HBM_CLOSE_SESSION, ex, false);
}
finally {
threadSession.set(null);
}
}

public static void beginTransaction() {
Transaction tx = threadTransaction.get();
try {
if (tx != null && !tx.isActive()) {
tx = null;
threadTransaction.set(null);
}
if (tx == null) {
if (mLogger.isInfoEnabled()) {
mLogger.info("Starting new database transaction in this thread.");
}
if (threadSession.get() != null && threadSession.get().isOpen()) {
threadSession.get().close();
threadSession.set(null);
}
tx = getCurrentSession().beginTransaction();
threadTransaction.set(tx);
}
else {
if (mLogger.isInfoEnabled()) {
mLogger.info("Using current database transaction in this thread.");
mLogger.info("Opening new Session for this thread.");
}
}
}
catch (HibernateException ex) {
Throw.loggable(HBM_BEGIN_TRANSACTION, ex, false);
}
finally {
if (threadSession.get() == null || !threadSession.get().isOpen()) {
getCurrentSession();
}
else {
threadSession.get().clear();
}
}
}

public static void commitTransaction() {
final Transaction tx = threadTransaction.get();
try {
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack())
{
Session s = getCurrentSession();
s.flush();
if (mLogger.isInfoEnabled()) {
mLogger.info("Flushing session and committing transaction of this thread.");
}
tx.commit();
}
}
catch (HibernateException ex) {
rollbackTransaction();
Throw.loggable(HBM_COMMIT_TRANSACTION, ex, false);
}
finally {
threadTransaction.set(null);
closeSession();
}
}

public static void rollbackTransaction() {
final Transaction tx = threadTransaction.get();
try {
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
mLogger.info("Trying to rollback database transaction of this thread.");
tx.rollback();
}
}
catch (HibernateException ex) {
Throw.loggable(HBM_ROLLBACK_TRANSACTION, ex, false);
}
finally {
threadTransaction.set(null);
closeSession();
}
}
}

Next installment I want to continue our ThreadLocal variable discussion and problems you can run into when using them.

Monday, July 21, 2008

Help Me ThreadLocal Variables!

I attended a local NoFluffJustStuff seminar last weekend and enjoyed every discussion I attended. Ted Neward was in excellent form as usual. There was one thing that bothered me though. There were quite a few attendees that did not know how to utilize ThreadLocal variables and some had never heard of them.
I'll discuss and demonstrate them here and in the next post I'll demo using hibernate Sessions with ThreadLocal variables. Hopefully, this will help out a lot of people.
ThreadLocal variables are instances of the java.lang.ThreadLocal<T> class. There are two methods (it has more) that we are concerned with get() and set(T value) which perform the normal accessor and mutator functionality. Here's the main point! These variables differ from the variables you are used to in that each thread that accesses a ThreadLocal variable via its get or set method has its own, independently initialized copy of the variable. That's where the class' name came from, the variable is local to the Thread that has it.
Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible. When a Thread dies all of its ThreadLocal variables are garbage collected if there are no references to them.
This gives you what I call poor man's thread safety. Other threads won't bother it and it won't bother other threads. So how can I utilize these variables? It's actually quite simple. Here's the example I promised.

Class UserHelper {
private static final ThreadLocal threadUser = new ThreadLocal();

/** Retrieves the user name of this thread. */
public static String getThreadUser() {
return threadUser.get();
}

/** Stores the user name of this thread. */
public static void setThreadUser(String username) {
threadUser.set(username);
}
}

This class stores the current user's name in a threadlocal variable attached to the current thread of execution and the Thread lugs it around wherever it goes. In any part of the application this user name can be accessed by simply calling the getThreadUser() method. Even though you may have two different threads executing the same part of an application, when the application calls the get method each thread returns it's own user's name. Simple huh?

Warning
Always remember that the ThreadLocal data is connected to the thread, not the user (in our example it has the user name but that's it) or anything else. A good idea is to delete the ThreadLocal data when it's no longer used.
MyThreadLocal.set(null);

We'll talk about the Hibernate ThreadLocal Session pattern in the next installment.

Friday, May 23, 2008

Entity Method Instances From hibernate.cfg.xml

Wouldn't it be cool if you could obtain an instance of a particular annotated method from a Hibernate entity by simply examining the hibernate.cfg.xml file? It's not as difficult as you may think.
The key to the whole process is knowing how to read the configuration file and manipulate what it returns. Let's examine some code that does just that. We'll examine all the classes in our config file and retrieve information on each of the methods annotated with @Id. We'll put this information in a map with the map's keys being the classes themselves and the values being Hibernate IdMetaData objects.

Map idMap = new HashMap();
1 Configuration config = new AnnotationConfiguration().configure();

2 for (Iterator iter = config.getClassMappings(); iter.hasNext();)
{
3 RootClass root = ((RootClass)iter.next());

try {
4 Class clazz = root.getMappedClass();

5 Method idGetter = root.getIdentifierProperty()
.getGetter(clazz).getMethod();
6 Method idSetter = root.getIdentifierProperty()
.getSetter(clazz).getMethod();
7 Class type = idGetter.getReturnType();
8 IdMetaData md = new IdMetaData();
9 md.setIdGetter(idGetter);
10 md.setIdSetter(idSetter);
11 md.setType(type);
12 idMap.put(clazz, md);
13 mLogger.info("mapping Id for " + clazz.getName());
}
catch (Exception e) {
throw new Error("unable to initialize annotation map");
}
}
Line 1 is the standard way to generate a Hibernate configuration instance. The Iterator of line 2 returns a Hibernate RootClass (line 3) for each of the defined classes in the config file. This class is the gateway to a lot of information.
root.getIdentifierProperty() in lines 5 and 6 returns a Hibernate Property object of the method marked with the @Id annotation. This allows access to the actual getter and setter methods. IdMetaData is a simple bean class that holds any information obtained from the RootClass object. Line 12 fills a HashMap with the class as the map key and the IdMetaData as the value. Once you know the trick you can programatically get at any information you wish to.
------------------
Developers read APIs, Engineers read the source code!

Wednesday, May 21, 2008

Whence the name?

The dining philosophers problem is an illustrative example of a common computing problem in concurrency.
Five philosophers sit at a table doing one of two things - eating or thinking. While eating, they are not thinking, and while thinking, they are not eating. The five philosophers sit at a circular table with a large bowl of spaghetti in the center. A fork is placed in between each philosopher, and as such, each philosopher has one fork to his or her left and one fork to his or her right. As spaghetti is difficult to serve and eat with a single fork, it is assumed that a philosopher must eat with two forks. The philosopher can only use the fork on his or her immediate left or right.

The philosophers never speak to each other, which creates a dangerous possibility of deadlock when every philosopher holds a left fork and waits perpetually for a right fork (or vice versa).

Visit the DP Problem link on the right to see how it turns out.