With ORM, the persistency codes have been already better. Instead of hardcoding queries, developers work directly with object. That looks promising. But now, have a look at the entity class:
@Entity @Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP) |
As you may see, the persistent code tangles the object model. To avoid this tangling, of course, we can write the mapping and the definition in mapping file. But, I'm not really fan of XML because it is not compiled and it has a tendency to be more verbose.
Furthermore, if applications don't care about id, why should we define ID. I remember that thinking of relation to other class as a primary key is not a good Object Oriented programming practice.
Furthermore, if applications don't care about id, why should we define ID. I remember that thinking of relation to other class as a primary key is not a good Object Oriented programming practice.
So, why don't write PersistenceAspect as the way to annotate the class to make it persistable, after all, using intertype declaration we can add a member and also the annotations ? That's exactly the idea coming to my mind this week, and I made a try to implement the PersistentAspect. In this article, I use EclipseLink as the ORM.
Let's start now. But before starting, let's write the class that persisting a Flight object.
public class FlightMain { "AF", "1204", "CDG", "201005100800", "NCE", "201005100910" ); "AF", "1274", "CDG", "201005101000", "NCE", "201005101110" ); private static Flight createFlight( SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm"); |
To start with, I don't want to have Id in my Flight class. All right, move it to the aspect then.
public aspect PersistentAspect { |
public privileged aspect PersistentAspect {
...
@Id private int Flight.id; execution( Flight.new()) && this(f); |
With this aspect definition , we can run FlightMain above. It should work...
Unfortunately, no. I had error because a colum did not exist. Inspecting the log, I had the following query:
INSERT INTO FLIGHT (
AJC$INTERFIELD$COM_SCATLING_PERSITENCE_PERSISTENTASPECT$ID,
ARRIVALTIME,
DEPARTUREAIRPORT,
ARRIVALAIRPORT,
DEPARTURETIME,
NUMBER,
AIRLINE)
AJC$INTERFIELD$COM_SCATLING_PERSITENCE_PERSISTENTASPECT$ID,
ARRIVALTIME,
DEPARTUREAIRPORT,
ARRIVALAIRPORT,
DEPARTURETIME,
NUMBER,
AIRLINE)
Of course, EclipseLink works with the woven class of Flight, and the woven class has that AJC$INTERFIELD...$ID instead of ID. Well, then it means that we need to explicitly define the column name for intertype declaration. That's what we're going to do:
public aspect PersistentAspect {
...
@Column(name="ID")
@Id private int Flight.id; execution( Flight.new()) && this(f); after(Flight f) : flightCreation(f) { f.id = generatedId++; |
With this modification included now, the FlightMain works fine, two Flight objects are stored in the database.
Not satisfied with extracting id from Flight, I also want to strip @Entity from Flight class and also the temporal type for arrivalTime and departureTime. My Flight class becomes:
public class Flight { |
And my aspect becomes:
public privileged aspect PersistentAspect { execution( Flight.new()) && this(f);
@Temporal(TemporalType.TIMESTAMP); @Temporal(TemporalType.TIMESTAMP); |
Conclusion and Last Remarks
In this article, aspect can be used as alternative to XML object mapping. At least, we can reduce the need of XML object mapping. I foun d the need to explicitly intertyped column with ID is not convenient. Maybe, AspectJ should weave the Column annotation itself.
No comments:
Post a Comment