Wednesday, December 7, 2011

How to Dynamically Add Entities to a Persistence Unit

With a simple Spring extension it's possible to crack open a PersistenceUnit and dynamically add additional entity classes. It's also possible to merge multiple PersistenceUnits, but that isn't shown here. And the wiring:

How to Disable Hibernate Cascading

If domain objects are used in multiple contexts, it's possible that cascading is not always desirable. Unfortunately, it's not possible to persistNoCascade(entity). The following is a crude hack that will disable cascading entirely. It is not toggle-able, however. That would be nice, but it's a tricky thing to pull off because SessionFactoryImpl, SessionImpl, and AbstractEntityPersister can't be proxied. And the following is how to wire it:

Friday, May 6, 2011

Extracting Collection Parameterized Type at Runtime

While the parameterized type of locally declared collections is erased at compile time, it actually is possible to extract the type off of a field at runtime. Here's how it's done:

That's all there is to it. Note, this trick will not work if the collection declaration uses a wildcard or generic parameter.

Tuesday, May 3, 2011

Multi-Field Bean Validation (JSR 303)

JSR 303 is excellent, with few glaring short-comings. However, the ability to access multiple bean properties within a single field level validator is surprisingly absent. The obvious solution is to just move the validator to the class level. It's annoying and ugly, but it works. Unfortunately, the bean property path on the ConstraintViolation now points to the class and not the field where validation failed. This problem can be resolved by explicitly adding the bean property path to your validator's annotation, and doing something like the following in your validator:

Monday, February 14, 2011

Embedding XML within JAXB Objects

If a JAXB object contains a String element of un-parsed XML, it can be a little tricky to represent.

First, you need to stop JAXB from attempting to unmarshal the embedded XML. This is done by intercepting the call to unmarshal the element in order to gain access to raw DOM node that JAXB has constructed. From here, it's simply a matter of converting the node into a String, which is written to a field. As you'd expect, for marshalling you need to do the opposite, turning the XML String into a DOM node. However, you must wrap your XML in a dummy, root tag prior to returning it. For example:

The above code utilizes a utility class to wrap basic W3C XML parsing. It's not doing anything special, but, if you're curious, the source is available here.

Your code should now be able to marshal/unmarshal embedded XML to a String field. This works fine and dandy as long as your XML does not contain namespaces. Namespaces pose a couple of problems. First, if the namespaces aren't declared at the root of the document, JAXB will blowup while parsing. Second, if there is a declared, but unused, namespace, JAXB will not preserve it.

The first problem can be solved by scanning your XML prior to unmarshalling, and attaching any namespace declarations that are discovered to the root node. This can be done in a variety of ways. I have a solution that's based on DOM4J that's available in my commons project here.

The second issue is really only a problem if something else in your application is depending on having certain namespaces defined. Unfortunately, JAXB does not have a simple flag to toggle between behaviors, but there is a way to preserve unused namespaces. You have to create a SAXSource, set a couple of namespace related flags on it, and feed it to your unmarshaller. It should look something like this:

JAXB has more than its fair share of quirks, but at least you can force it to do just about anything.

Saturday, February 5, 2011

JAXB Packing Bug

It appears to be a little known fact that Java 1.6 includes a JAXB implementation -- no need for external libraries. However, the version that's currently bundled has an annoying bug related to how it packs lists. Let's say that your XML contains a list of items that you'd like to unmarshal and represent internally as a map. One might thing that all you'd have to do is the following:

And what you'll end up with is an empty map. Here's what happened:
  1. Something.getList() is called and returns null.
  2. JAXB creates a new ArrayList, and passes it to Something.setList(). At this point there is nothing in the list.
  3. JAXB unmarshals all of the items, appending them to the list.
I'm sure you see the problem. Fortunately, there is a solution. The latest version of JAXB (available here) has fixed the problem. It follows the same flow described above, but with one additional step. It calls Something.setList() a second time after populating the list.

Upgrading your version of JAXB is a two step process.
  1. Put the new jars on your classpath or install them to your Maven repository.
  2. Prior to unmarshalling, call: System.setProperty("javax.xml.bind.JAXBContext", "com.sun.xml.bind.v2.ContextFactory");

Wednesday, February 2, 2011

Domain Model Marshalling

I have been attempting to marshal/unmarshal arbitrary parts of a complex domain model, and was unable to find an adequate solution for the cyclic reference problem anywhere.

Failed solutions:

  • JAXB's Unofficial Guide has some good suggestions, but they require a fixed parent-child relationship.
  • Castor handles cycles out of the box, but there's data loss in that it refuses to preserve back references.
  • This guy has an interesting solution that handles marshalling extremely well, but, at least just going off the code posted, unmashalling will never work.

Here's my hacky, yet functional, solution:

First, define an abstract class as follows:

All of your domain objects must extend this class. It provides the IDs that will essentially be used as surrogate keys when your objects are marshalled. As you go through your classes extending Marshallable, annotate all of your properties with @XmlIDREF. For example:

Now, when JAXB marshals these objects it's going to simply insert references, which solves the cycle problem. However, it creates a new containment issue. If you were to marshal your objects now, you'd generate a well formed XML tree full of references that point nowhere. I'm not convinced this is the best solution, but here's my crack at the issue of containment.

You'll need to wrap every object that you marshal in this wrapper. It flattens the entire graph so that ever instance of Marshallable is a sibling.

Here's an example marshal:

Here's an example unmarshal:

It isn't pretty, but that should do the trick.