<GEEK BLOG ENTRY>
I ran into a very frustrating problem this evening, causing me to stay much later than I had intended, and to miss out on some fun socializing event that I was looking forward to. Unfortunately, there was little to no useful information on the Internet as Google was coming up with few and useless results.
I hope this post saves some poor soul from the same fate.
The Problem
I’m using the
Hibernate library for
persistence with a
JBoss EJB using
JPA. My code is sprinkled with
annotations, my
hibernate.cfg.xml file is clean, and I have no
*.hbm.xml files. My code compiles. And it runs.
However.
When I try to access something that uses the Hibernate library, I get an odd message about “Duplicate Collection Role Mapping“.
The class in question contained a Set interface and a HashSet implementation for a member.
So, I commented out this container and tried again, hoping to simplify the problem.
This time I was greeted with a “[Mappings] duplicate import” and a “DuplicateMappingException: Duplicate class/entity mapping” set of error messages.
The only related web pages was a handful of archive with people asking similar questions in various online forums.
Almost always these fell into one of three responses:
- You’ve got a problem with the mapping element in your hibernate config file.
- You’ve got annotations and and class.hbm.xml file doing something wrong.
- This is an old bug in JBoss.
None of the symptoms existed in my case.
Here’s How I Solved It
Turns out that Hibernate makes the recommendation that you build a
HibernateUtil helper class. Inside it, you’re supposed to make a singleton of the SessionFactory (and in the case of JBoss, you should use
JNDI).
A co-worker had refactored the AnnotationConfiguration() to store a single copy, however, the routine that returned it happened to call .configure(…) on it before returning it each time. An honest mistake, which got integrated silently into my code when I pulled the latest version from version control.
Because .configure(…) was being called twice, to Hibernate it did look as if I had duplicate mapping directives in my hibernate config file.
Correcting the HibernateUtil method, which handled setting up and returning the AnnotationConfiguration solved the problem.
</GEEK BLOG ENTRY>