Tuesday, November 17, 2009

Adempiere references in Plain Old Java


Right now, I'm learning Adempiere and finding ways on how to hack it apart (and put it together again). I'll be "reporting" my findings on this blog on how things are done and how some of these concepts can actually be used in Java in general.

One thing that interests me in Adempiere is the Rapid Application Development feature, especially when building rich CRUD based stuff. Adempiere has this concept of "everything must have metadata". By manipulating this metadata, CRUD based application can easily be done.

In the general Java world, metadata manipulation used to create CRUD based apps is not new. Frameworks such as OpenXava (who claim to have beaten RoR development record time - apparently that article is not accessible anymore) is attracting much attention. One thing Adempiere does differently is by qualifiying relationships between Domain Objects (of course in Adempiere, the Domain Objects are Relational Database Tables since Adempiere uses direct / semi-direct SQL access). Disclaimer - I'm not an OpenXava expert, so if OpenXava does these stuff too, please do tell.

Imagine if we can port this to the Java world in general

[If you are not familiar with the concept of Reference in Adempiere, I would like to redirect you to my good friend, Red1's, tutorial ]

In Adempiere you can qualify a reference (a link from one table to another table). For example you can say that a reference is "Searchable". When the reference is rendered, you would see a "search box" that is linked to data from the reference table. You can type away a search term and the reference table will be searched.

How can we do this in Java in general?

To demonstrate this, we'll look at an example: Imagine that I have 3 entities, User (plain old User - ok, maybe not so old :) ) , PurchaseRecord (a record of a purchase made by the user) and Product (the actual product the user purchase)


Using JPA or Hibernate I could have codes representing the entities as:

@Entity
public class User{
@OneToMany
private Set purchaseRecords;
}

@Entity
public class PurchaseRecord{
private Product product;
private int number;
private Date purchaseDate;
}

@Entity
public class Product{
private String name;
private String unitPrice;
}

If I'm using plain old CRUD generator , I would create a User list. Clicking on a User from the list would give me the details of that particular user and a list of PurchaseRecords. That list is presented as is. If I'm lucky, the CRUD generator will allow me to page or sort the data. One thing I do not have is a quick access to a particular record and the subsequent Product attached to that Record. But, imagine if I can do this:

@Entity
public class User{
@OneToMany
@Display(qualifier="PurchaseRecord.product.name")
@Searchable(by="PurchaseRecord.product.name")
@DefaultFilter(qualifier="PurchaseRecord.purchaseDate=DateQualifier.TODAY")
private Set purchaseRecords;

}

Automatically, when I click on a user, I would still see a list (but this time a list of names of products, which is more palatable) and also a text box, a dropdown list and a button.

The textbox represents a search term box. You can search your PurchaseRecord by its name. Enter your search term and click on the button. The dropdown list represents filters. By default, PurchaseRecord will be filtered by date=TODAY (only today's entry is displayed). The user can always choose any other available filters.

Of course I'm just imagining stuff here and I'm sure there are some gaps that need to be filled in (for example, does having a @Display tag violates MVC) but the concept of Reference in Adempiere is really powerful. Hopefully someone could bring this concept to the JPA/Hibernate world.

2 comments:

Redhuan D. Oon said...

Good analysis of the codebase in the Compiere/ADempiere family. Keep it up and in due time sure to become a reference blog for serious java hacks into the codebase. Will exchange ideas everytime we meet. :)

Mauricio Ferreyra said...

Thanks! I have a question, I want to create a new CRUD in adempiere, I follow the tutorial "new Table + Window" from wiki. But I cannot see the window or menu. Where I can find tutorials or documentation ?