I'm having the same problem with Hibernate 3.1.3. Did you end up solving yours?
For the curious:
I stepped through the hibernate code in the debugger. The NullPointerException in CriteriaLoader.applyLocks happens because its local "entityAliases" array is null; that array is null because the "aliases" field (defined in OuterJoinLoader) is null. So the question is, where did (or should) OuterJoinLoader.aliases come from? Well, it comes from a method called initFromWalker(JoinWalker walker), which calls walker.getAliases().
So now the question is, what's up with this JoinWalker? In this case, it is a CriteriaJoinWalker, which extends AbstractEntityJoinWalker.
Where, then, does (or should) JoinWalker.aliases get initalized? It happens in a method called initPersisters. This method, in turn, is called by the AbstractEntityJoinWalker.initAll method.
Why isn't CriteriaJoinWalker calling that initAll method? Here's the relevant code in the CriteriaJoinWalker constructor:
Code:
if ( translator.hasProjection() ) {
resultTypes = translator.getProjectedTypes();
initProjection( ... );
}
else {
resultTypes = new Type[] { ... };
initAll( ... );
}
So, when there's a projection, we don't call the initAll method, and so the aliases field is never initialized. As a newbie, I can't distinguish between the following possibilities:
1. It's not legal to use setLockMode and projections together.
2. It is legal, and the lack of initialization in this case is a bug.
3. It is legal, but we're doing it all wrong; a more experienced user would do [some clever thing].
Of course, even cases 1 and 3 are arguably bugs; NPE is not a helpful error message.