Since you were curious, I'm actually in the process of evaluating hbm2java and xDoclet for use with a new project, so opinions on that debate are greatly appreciated.
As for the problem at hand, I have tried the "extends" meta-attribute. The problem is that hbm2java re-generates the setters and getters for the sub-class. Here's what I have:
Persistent.java (hand-coded)
Code:
public class Persistent {
private Long id ;
private Date createTime ;
public Long getId() {return this.id ;}
public void setId(Long id) { this.id = id ; }
public Date getCreateTime() { return this.createTime ; }
public void setCreateTime(Date createTime) { this.createTime = createTime ; }
}
Contact.hbm.xml (hand-coded xml snippet)Code:
<class name="Contact">
<meta attribute="extends">Persistent</meta>
<id name="id" type="long">
<generator class="native"/>
</id>
<property name="createTime" type="date" />
<property name="firstName" type="string" length="32" />
<property name="lastName" type="string" length="32" />
<property name="companyName" type="string" length="32" />
<property name="address1" type="string" length="128" />
<property name="address2" type="string" length="128" />
<property name="city" type="string" length="128" />
<property name="postalCode" type="string" length="32" />
<many-to-one name="state" class="State" />
<many-to-one name="country" class="Country" />
<property name="email" type="string" length="64" />
<property name="workPhone" type="string" length="32" />
<property name="homePhone" type="string" length="32" />
<property name="mobilePhone" type="string" length="32" />
<property name="otherPhone" type="string" length="32" />
</class>
Contact.java (generated by hbm2java)Code:
/**
* Contact generated by hbm2java
*/
public class Contact extends Persistent implements java.io.Serializable {
// Fields
private Long id;
private Date createTime;
private String firstName;
private String lastName;
private String companyName;
private String address1;
private String address2;
private String city;
private String postalCode;
private State state;
private Country country;
private String email;
private String workPhone;
private String homePhone;
private String mobilePhone;
private String otherPhone;
// Constructors
/** default constructor */
public Contact() {
}
/** constructor with id */
public Contact(Long id) {
this.id = id;
}
// Property accessors
/**
*
*/
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
/**
*
*/
public Date getCreateTime() {
return this.createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
*
*/
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
(... snip ...)
}
As you can see, hbm2java generated code that shadows the base class' id and createTime properties. I suppose I could change the Persistent class and declare getId/setId, etc. to be abstract methods, but this effectively prevents me from coding property-specific behavior.
I could also take out the following lines from Contact.hbm.xml:
Code:
<id name="id" type="long">
<generator class="native"/>
</id>
<property name="createTime" type="date" />
And this would result in the java code that I want. The problem is that I would not have the database mapping that I wanted. (I want id and createTime to be part of the Contact table.)
Are there other ways to manipulate hbm2java output? (I'd rather not resort to tweaking the Hibernate source, or even "pojo.vm".) Or, should I declare the base class properties (set/get id and createTime) abstract? Or should I go with XDoclet?