Quartz and Hibernate

Posted on October 25, 2008 by Brian Tajuddin

I recently put Quartz into a project with Hibernate and ran into a strange problem. Every time I'd try to create a new JobDetail, I would get this exception:

java.lang.NoSuchMethodError: org.apache.commons.collections.SetUtils.orderedSet (Ljava/util/Set;)Ljava/util/Set;

I had the right version of Jarkarta Commons Collections in my classpath. I couldn't figure out what was going on for quite some time. I eventually realized that too many JAR files from Hibernate were being pulled in. Hibernate ships with a file called checkstyle-all.jar which is not used at runtime. It runs checkstyle (obviously). However, this includes all of checkstyle's dependencies, including an old version of commons collections. Once I removed it from the classpath (or at least got the real commons JAR earlier in the classpath) everything worked fine.

Inherited Embedded IDs

Posted on October 17, 2008 by Brian Tajuddin

I recently ran into a difficult problem using Hibernate through JPA. I had two tables that were effectively the same but had to be separate for various database optimization reasons. The two tables had equivalent primary key definitions. That definition was a composite key based off of two foreign keys. Here is the general view of what I had.

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Entity {
private IdClass _id;

@EmbeddedId
public IdClass getId() { return _id; }
protected void setId(IdClass id) { _id = id; }
}

@Entity
@Table(name="table_a")
public class EntityA extends Entity {}

@Entity
@Table(name="table_b")
public class EntityB extends Entity {}

@Embeddable
public class IdClass {
// a couple foreign keys
}

This caused some problems. There is a point in normal execution where we have to actually copy the values from one table to another. It turns out that the IDs are actually bound to a table as well as long as they are attached to the context. This made things very messy. I decided that it would be better for each of them to have their own IDs anyhow. I thought it would be easy to use inheritance on this. It was somewhat easy in the end, but there were definitely issues. Here is how I finally got everything working.

@MappedSuperclass
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Entity<T extends IdClass> {
private T _id;

@Transient
public T getId() { return _id; }
protected void setId(T id) { _id = id; }
}

@Entity
@Table(name="table_a")
public class EntityA extends Entity<IdClassA> {
@EmbeddedId
public IdClassA getId() { return super.getId(); }
}

@Entity
@Table(name="table_b")
public class EntityB extends Entity
<IdClassB> {
@EmbeddedId
public IdClassB getId() { return super.getId(); }
}

@MappedSuperclass
@Embeddable
public abstract class IdClass {
// a couple foreign keys
}

public class IdClassA extends IdClass {}

public class IdClassB extends IdClass{}

The secret sauce here is the getId() method in the two entity child classes. I tried several things before finding this. Without this, you will likely be getting ClassCastExceptions every time you try to retrieve one of these things. It would appear that it is retreiving something that is of the parent type but not the child. I don't really understand what is going on there. The other error I got (and can't remember the exact flavor of incantation to get it) involved a message saying that IdClassA had no id property.

All in all, it isn't a terribly complex solution, but it took a while to find the right combination of annotations and the magic getId() method in the subclasses. That was the hardest part to find.

Yahoo! Site Explorer: A Step Backwards

Posted on October 07, 2008 by Brian Tajuddin

I have been using Yahoo! Site Explorer for some time to track my site's status on the Yahoo! search engine. I have to say that I'm somewhat partial to Yahoo! for a couple reasons.

First, they index a lot more of my pages. They currently have almost 200k pages indexed on my site. Second, they provide more information about how they view your site in a real-time manner. Sure, it's not completely real time, but you can actually see changes occurring.

For the record, I also use the webmaster tools for Google and Microsoft Live. Both of them suck pretty bad.

Recently, I noticed that Yahoo! had a link to the "new" Site Explorer. I took a look and was pretty annoyed by what I saw. I guess I was alone because they've launched it. It is a step backward in useful design. The functionality is almost exactly the same as the previous version. They've spruced up the buttons a bit and added a little more color. Otherwise, they moved some navigational items from the top to the left and made the useful area of the screen 10% smaller. That's not enough, though. They decided that all this variable width stuff is useless. The information column is now 772 pixels wide. Sure, it fits perfectly on a 1024x768 screen. It's tiny on my 1280x1024 screen.

I cannot fathom what would make them do this. In the world where larger screens are more common, why would you tailor a site to the screen size people were using 5 years ago. I haven't seen an LCD monitor with a 1024x768 native resolution in years.

My advice to anyone out there is to fire any web designer who will not make their design adjust to the width of the user's browser window.

Chrome's marketshare

Posted on September 15, 2008 by Brian Tajuddin

A brief look at how Google Chrome is doing.[Read More]

jMock and interfaces galore

Posted on August 09, 2008 by Brian Tajuddin

The ASM pain is now over with, I think. I've tried various mocking packages and settled on jMock. There really isn't a huge difference between jMock and EasyMock. In fact, they both use CGLib. However, there are some subtle differences.

First, jMock integrates better with JUnit 4.4. This is pretty cool. If I were so inclined, I could specify exactly which mocked methods are called and the sequence in which they should be called. I can even specify several sequences. Then, at the end of each test, it would check the expectations and throw an exception. I also like the smaller overhead of jMock. EasyMock forces you to perform a lot more setup overhead for each mocked object. This can be pretty annoying. jMock simlpy makes me annotate the class, create a Mockery (I love the jMock terminology), create the mock, put it where it belongs, and create Expectations. There is no need to call a method to start the replay because I'm not calling the methods on the actual mocked object to set the expectations.

Second, jMock uses CGLib but provides a dependency-free version of the JAR. This allows me to more safely put it at the front of the classpath. I have used this a bit with hibernate being called and see no issues.

Finally, if you need to mock a class rather than an interface, you have to use an Imposteriser. That has to be the best word that I've ever typed into code. Therefore, jMock wins style points.

Of course, I have done a lot of work on this and just now realized that I'm only mocking a single class. That class is used in a package that doesn't need to call hibernate in the unit tests. That makes my life a lot easier. This is mostly due to the fact that one of the custom service dispatchers we use is a final class. That made it impossible to mock. I ended up creating a singleton that my unit tests could replace. Since I wrote it, I could make an interface for it. At this point, the only thing class I'm mocking is InitialLdapContext. I think this is a pretty good situation.

There you have it. ASM pain still exists in the world, but I've found my way around it.

ASM is not my friend

Posted on August 07, 2008 by Brian Tajuddin

I am currently working on cleaning up our unit tests at work. Our service code calls several other services within the company. However, we don't necessarily want those called during the unit tests. Development-level services are notoriously unreliable. I have started using EasyMock 2.3 to mock the interfaces for our dependencies. However, some of the things we need to do require mocking classes. Enter EasyMock Class Extensions 2.3.

I first tried to use the class extensions and immediately got a NoSuchMethodError when running my tests. To make a long (and painful) story short, Hibernate imports a version of ASM that is newer than the one used by EasyMock Class Extensions. Luckily, the particular package I'm using doesn't need Hibernate. It only gets included in the classpath because it is in the list of transitive dependencies. However, once I start using Hibernate, I fear it will not work. I will be trying this out today. If anyone has any ideas, though, please let me know.