Tuesday, May 13, 2008

Generate hibernate composite-id using XDoclet

Few tables don't allowed to have a serial id just as modern table as in the appfuse by default. Ok, I mention one table of it: Financial, it has four PKs which are FK from four different tables: DimChartaccount, DimCurrency, DimLocation, and DimTime.

I've search the net and knew that it called composite-id (multiples id), and browse again to find how to generate its hbm directly from my pojo and got one link : Franklin Garcia's blog, it shows how to do it, but I've try it but unfortunately it fails to generate as I need, it cannot generate the composite-id part, but now I already fix it. here's how to do it, hope it helps:
  • name it still as id, but the type not as integer anymore, and no need generator class="increment", its type is PkFinancial. It's name must id because Ive try to name it with pkFinancial but I've got error fails in setter when I deploy it
  • PkFinancial is your own class, it must implements Serializable, and the properties are all of the PKs
/**
* @hibernate.class table="FINANCIAL"
*/
public class Financial extends BaseObject {
PkFinancial id; //must id, cannot name it as pkFinancial
Double saldoRupiah;
/**
* @hibernate.id name="id" class="jesperBlog.PkFinancial" //need to mention it's class
*/
public PkFinancial getId() {
return id;
}
public void setId(PkFinancial id) {
this.id = id;
}
/**
* @hibernate.property column="SALDO_RUPIAH" type="double" //usual property
*/
public Double getSaldoRupiah() {
return saldoRupiah;
}
public void setSaldoRupiah(Double saldoRupiah) {
this.saldoRupiah = saldoRupiah;
}
}

public class PkFinancial extends BaseObject { //must implements Serializable, BaseObject already done it
DimTime dimTime;
DimLocation dimLocation;
DimChartaccount dimChartaccount;
DimCurrency dimCurrency;

/**
* @hibernate.many-to-one name="dimTime"//just usual property, in my case it's many-to-one
* column="TIME_KEY" class="jesperBlog.DimTime"
*/
public DimTime getDimTime() {
return dimTime;
}
public void setDimTime(DimTime dimTime) {
this.dimTime = dimTime;
}
/**
* @hibernate.many-to-one name="dimLocation" column="LOCATION_KEY" class="jesperBlog.DimLocation"
*/
public DimLocation getDimLocation() {
return dimLocation;
}
public void setDimLocation(DimLocation dimLocation) {
this.dimLocation = dimLocation;
}
//oter getters setters
}

And the generated hbm looks like this:
...
<hibernate-mapping>
<class name="jesperBlog.Financial" table="FINANCIAL">

<composite-id name="id" class="jesperBlog.PkFinancial">
<key-many-to-one name="dimTime" class="jesperBlog.DimTime" column="TIME_KEY"/>
<key-many-to-one name="dimLocation" class="jesperBlog.DimLocation" column="LOCATION_KEY"/>
<key-many-to-one name="dimChartaccount" class="jesperBlog.DimChartaccount" column="ACCOUNT_KEY"/>
<key-many-to-one name="dimCurrency" class="jesperBlog.DimCurrency" column="CURRENCY_KEY"/>
</composite-id>

<property name="saldoRupiah" type="double" column="SALDO_RUPIAH"/>
...
</class>
</hibernate-mapping>

No comments: