Showing posts with label JPA. Show all posts
Showing posts with label JPA. Show all posts

Monday, March 09, 2009

Introduce JAXB to your POJOs

Suppose you want to keep your POJO really a POJO? If you use JPA annotations on a class, is it still really a POJO? A POJO should be usable as a domain object independent of whether it came from a database, or from a remote service. So If I see @Entity on your POJO, I know it is really a database object, and I start thinking all about it's dependencies, do I need a transaction, do I need a JDBC connection, what JAR has the JPA annotation, maybe it isn't in my JRE, no more a "plain" Java object.

Ok, but I want to store my POJO in a database, what do I do? Ok, that will be my next article... Today, what if I want to use JAXB to serialize the POJO as XML? Then I need to use @javax.xml.bind.annotation.XmlRootElement to annotate the class. That just ruined my POJO. AspectJ can add fields, methods, annotations, and parents to classes. Why not just introduce the JAXB annotations necessary to marshal the object at runtime just for the situation that I need?

Here is my POJO:
public class Order {
private String number;
private String product;
private String customerEmail;
private String customerName;
}


Now, here is the POJO with the JAXB annotation:
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Order {
private String number;
private String product;
private String customerEmail;
private String customerName;
}


Isn't marshaling an object to XML a totally different concern from if an Order needs the customer's email address? So, let's separate those two concerns:

import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public aspect Jaxbify {
declare @type : Order : @XmlRootElement;
}

This aspect introduces the XmlRootElement annotation to the Order class, keeping Orders, Orders.
Next time I'll show how to run this example.

Wednesday, December 05, 2007

How Important is Symmetry in JPA?

When you are designing a domain model using JPA or hibernate or another declarative approach to ORM, you must decide the cascade rules for creating and deletign objects that are related to each other. When you have a one-to-many relationship between two objects, when an object is persisted, you need to decide if the related object should be automatically persisted as well, or should you have to persist each object?
To me it seems that this must be made symmetrical, that is if you cascade create, then you should cascade delete as well. Any other rule than this makes your system more complicated. Intuition should be available to one trying to understand your domain model, and symmetry is a part of nature, so it will be intuitive to expect a consistent behavior. If you are using JPA, the cascade rules will be in the code so you will see the rule with the code so it will be evident of your choice. In the case that you are using Hibernate from an XML configuration file that is not visible at the same time as the source code, then you will have to remember the cascade rules, minimizing the burden of memorizing too many things can help in comprehending your model, a consistent rule of always cascade create with delete will eliminate this from your efforts.
In a more encapsulated direct approach, I recommend that a new annotation of @Aggregation be created that has this behavior as it's meaning, it is simple and precise as to the intent. AspectJ can be used to create this annotation, and with JPA annotations as the ORM approach, the needed annotations can be injected behind the scenes. This seems like a nice clean use of AOP to help in using of JPA.

Labels