Hibernate and and the “Found two representations of same collection” error

Last night I spent an extended work day trying to track down the source of a Hibernate exception that I have never encountered before. The application in question is a simple data loader application that reads in an XML file populates a Hibernate object graph. The data in the XML file changes from day to day and if element exists in the XML file one day and not the next, the entity is removed from the object graph. All had been working fine until suddenly I started seeing this in my error logs:


Caused by: org.hibernate.HibernateException: Found two representations of same collection: ...

The odd thing was that there can ever be more than one representation of this collection in the application, so I had wonder WTF? I then came across this thread on the Hibernate Forums, but I wasn’t doing anything with Session.clear(). In fact, we weren’t doing manual session management (i.e. flush, etc.).

To make a long story short, the issue was traced down to mapping error. The object hierarchy is as follows:

parent +
       + Component +
                   + component attribute

The removals were being performed on the component by removing a component attribute the Component.componentAttributes collection. The component attribute maintains a bi-directional relationship with its owning component. However, the mapping for the component attributes parent was as follows:

@NaturalId
@ManyToOne(fetch = FetchType.LAZY,
           cascade = { CascadeType.PERSIST,
                       CascadeType.MERGE,
                       CascadeType.REMOVE })
private Component parentComponent;

Note the CascadeType.REMOVE. This meant that when this child was removed, it’s parent would also be removed, hence the duplicate collection. The issue was resolved once the mapping was changed to:

@NaturalId
@ManyToOne(fetch = FetchType.LAZY,
           cascade = { CascadeType.PERSIST,
                       CascadeType.MERGE })
private Component parentComponent;

Of course this could have been caught sooner had some unit tests been a little better, but the cause of this issue sure was a bitch to find. In end it was a subtle mapping issue that ended up getting introduced and wreaking havoc on my day. Hopefully this post can spare someone else some lost hours.

Hibernate and and the “Found two representations of same collection” error

RESTEasy and Seam

There has been some discussion lately regarding integrating JBoss Seam with RESTEasy. Jay Balunas recently made about post on his thoughts on ths subject, so I thought I’d post some of mine. For the record, I am a huge fan of Seam and I think there’s definitely a place for Seam in RESTEasy, so here’s a few of my musing on the subject:

Seam Managed Persistence Contexts

This is a really great feature of Seam and it adds a lot of value to a framework like RESTEasy. If you have a resource that returns a entity that is a complex object graph that will be marshalled to XML, you have a high potential for hitting a LazyInitialzationException. This is especially true if you’re calling a SLSB to get your data because the marshalling process is handled on the web tier, outside of the EJB transaction. If the entity was not fully initialized, your object graph will be incomplete and you will get a LazyInitialzationException. In the initial version of RESTEasy, I used a Seam managed persistence context in order successfully marshall a complex entity using JAXB without getting a LazyInitializationException. I could have written a filter that was similar to the Spring OpenSessionInViewFilter to span the transaction over the entire HTTP request, but Seam made this problem transparently go away in very elegant manner.

Transactions/Conversations

Conversations are one feature of Seam that cause a lot of folks to raise concerns about the stateful nature of the framework in regards to REST. However, I think in some instances, some of the conversational aspects of Seam can be utilized in a RESTful design. Take this thread on the JSR-311 mailing list from Bill regarding Transactions in JAX-RS:

No, I don’t want JAX-RS to have a transaction model :)

One pattern I’ve seen in REST is how they solve distributed
transactions.  The pattern seems to be

/transactions/{tx-id}/.../whatever/your/real/resources/are

So really the transaction resource is allowed to contain any resource
the server supports.  (I hope you are following me, if not I’ll expand).

IMHO, this is something I think Seam could lend a hand with. Taking both Seam’s support for conversations and jBPM, you could conceivably use a long-running conversation to implement such a feature whereby you might end up with something like:

/transactions/{conversation-id}/.../whatever/your/real/resources/are

It’s not a fully baked idea, nor might it be quite the same thing that Bill is talking about. However, it could potentially be RESTful if implemented properly and Seam already provides the plumbing for this out of the box.

Entity Resources

The Seam framework (as in org.jboss.seam.framework), offers a lot of convenience features that make working with JPA and Hibernate a breeze. I had a silly idea a while a back about how to expose entity beans as a resource without the need for a dedicated resource class. The idea wasn’t fully baked (and in hind sight, those details are actually kinda crappy and overly verbose), but the general idea was to make it easy to navigate elements of an object graph. For example, if you were to access the following URI:

http://myhost/contacts/12345

You’d end up with the full object graph as XML for contact ID 12345. If you just wanted to look at one address for that contact, you should be able to call:

http://myhost/contacts/12345/addresses/home

And you would get just the XML element for the contact’s “home” address. What I don’t want to do is create a separate resource class for each element and each collection type in the object graph. You shouldn’t have to create a ContactsResource, ContactResource, AddressesResource, AddressResource, etc. Ideally, you should be able to have one class, or just the entity itself, that can represent the resource. I’m currently working to refine this idea for RESTEasy and much of the Seam framework API could be useful in making this a reality.

I could go on, but I think there’s a lot of value that Seam can bring to RESTEasy.

RESTEasy and Seam

Using a SessionFactory in a WebLogic Cluster

If you’re trying to bind a Hibernate SessionFactory to a WebLogic cluster and you’re getting the following error message:

“Conflict start: You tried to bind an object under the name [{factory.name}] in the JNDI tree. The object from [{factory.name}] is non-clusterable, and you have tried to bind more than once from two or more servers. Such objects can only be deployed from one server.”

You may want to add this to you hibernate.cfg.xml file:

<property name="hibernate.jndi.weblogic.jndi.replicateBindings">false</property>

This has worked for me with WebLogic 8.1, and it is probably applicable to other WebLogic versions as well. While I haven’t come across any solid documentation which states that the SessionFactory is not a clusterable object, it appears that this is the case. This isn’t a big deal however, especially if you’re not using a second-level cache. If you need to use a second-level cache, you’ll want to use a cluster-aware cache such as JBoss Cache or Tangosol Coherence.

Using a SessionFactory in a WebLogic Cluster