使用 Hibernate时,可以由POJO生产出hbm.xml映射文件和数据库,前提是必须在POJO中使用XDoclet.的@Hibernate.Tags插件.(或JDK5的注解)
与XDoclet 1 不同,XDoclet 2在Codehaus.org上,
! XDoclet 2显式地支持复合主键.
简单的使用介绍在Hibernate的文档中可见: http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#mapping-xdoclet
详细的tag说明
X1: http://xdoclet.sourceforge.net/xdoclet/tags/hibernate-tags.html
X2: http://xdoclet.codehaus.org/HibernateTags
续:POJO--XDoclet 1--hbm.xml的过程中,如果表具有复合主键,标签要怎么写?
环境:MyEclipse 5.0GA中包含的XDoclet插件版本仍仅支持XDoclet 1,为了不增加额外的插件,就用它了;
解决方法纪要:
我在通用报表系统5.0设计器的开发中使用XDoclet来生成Hibernate映射文件,遇到了复合主键的问题。在具有复合主键的情况下,我的POJO采用一个主键Bean的方式加一个属性Bean的方式,(因为X1的@hinernate.id 在每个class中最多只能有一个,多于1的会自动忽略)也即“Components as composite identifiers” 方式。这方面的资料实在太少,东查西找,没有解决,又连猜带蒙,试验了几十遍才搞定了,哀啊!怎么文档这么残呢!
关于如何在Myeclipse中使用xdoclet就不提了,把两个POJO贴出来,一切就清楚了:
/**/
/*
* 此JavaBean由Genesis自动生成,请勿随意修改
* 生成时间:Tue Oct 17 13:41:53 CST 2006
*/
package
cn.tohot.grs5.po;
import
org.apache.commons.lang.builder.EqualsBuilder;
import
org.apache.commons.lang.builder.HashCodeBuilder;
import
org.apache.commons.lang.builder.ToStringBuilder;
import
org.apache.commons.lang.builder.ToStringStyle;
import
java.math.BigDecimal;
/** */
/**
* @hibernate.class table="detail"
*/
public
class
TestDetailPO
{
/** */
/**
* 复合主键
*/
private
cn.tohot.grs5.po.TestDetailPK pk ;
/** */
/**
* generated by Genesis
* @hibernate.id class="cn.tohot.grs5.po.TestDetailPK"
*/
public
cn.tohot.grs5.po.TestDetailPK getPk ()
{
return
pk;
}
/** */
/**
* generated by Genesis
*/
public
void
setPk ( cn.tohot.grs5.po.TestDetailPK pk )
{
this
.pk
=
pk;
}
/**/
/*
**** 字段 ****
*/
private
String goods;
private
BigDecimal qty;
private
BigDecimal price;
private
BigDecimal amt;
private
String orderNo;
/** */
/**
* generated by Genesis
* @hibernate.property column="goods" not-null="false"
*/
public
String getGoods ()
{
return
goods;
}
/** */
/**
* generated by Genesis
*/
public
void
setGoods ( String goods )
{
this
.goods
=
goods;
}
/** */
/**
* generated by Genesis
* @hibernate.property column="qty" not-null="false"
*/
public
BigDecimal getQty ()
{
return
qty;
}
/** */
/**
* generated by Genesis
*/
public
void
setQty ( BigDecimal qty )
{
this
.qty
=
qty;
}
/** */
/**
* generated by Genesis
* @hibernate.property column="price" not-null="false"
*/
public
BigDecimal getPrice ()
{
return
price;
}
/** */
/**
* generated by Genesis
*/
public
void
setPrice ( BigDecimal price )
{
this
.price
=
price;
}
/** */
/**
* generated by Genesis
* @hibernate.property column="amt" not-null="false"
*/
public
BigDecimal getAmt ()
{
return
amt;
}
/** */
/**
* generated by Genesis
*/
public
void
setAmt ( BigDecimal amt )
{
this
.amt
=
amt;
}
/** */
/**
* generated by Genesis
* @hibernate.property column="orderNo" not-null="false"
*/
public
String getOrderNo ()
{
return
orderNo;
}
/** */
/**
* generated by Genesis
*/
public
void
setOrderNo ( String orderNo )
{
this
.orderNo
=
orderNo;
}
/** */
/**
Overriden toString method.
*
@return
string
*/
public
String toString()
{
return
ToStringBuilder.reflectionToString(
this
,
ToStringStyle.MULTI_LINE_STYLE);
}
/** */
/**
Overridden equals method.
*
@param
o object
*
@return
true/false
*/
public
boolean
equals(Object o)
{
return
EqualsBuilder.reflectionEquals(
this
, o);
}
/** */
/**
Creates object hash code.
*
@return
int
*/
public
int
hashCode()
{
return
HashCodeBuilder.reflectionHashCode(
this
);
}
}
/**/
/*
* 此JavaBean由Genesis自动生成,请勿随意修改
* 生成时间:Tue Oct 17 13:41:53 CST 2006
*/
package
cn.tohot.grs5.po;
import
org.apache.commons.lang.builder.EqualsBuilder;
import
org.apache.commons.lang.builder.HashCodeBuilder;
import
org.apache.commons.lang.builder.ToStringBuilder;
import
org.apache.commons.lang.builder.ToStringStyle;
import
java.io.Serializable;
/** */
/**
* detail 's composite key
*/
public
class
TestDetailPK
implements
Serializable
{
/** */
/**
* TODO 请设置此处的serialVersionUID值(建议根据提示由eclipse自动生成)
*/
//
private static final long serialVersionUID ;
/**/
/*
**** 主键字段 ****
*/
private
Integer lineNo;
private
String id;
/** */
/**
* generated by Genesis
* @hibernate.property column="lineNo" not-null="true" length="32"
*/
public
Integer getLineNo ()
{
return
lineNo;
}
/** */
/**
* generated by Genesis
*/
public
void
setLineNo ( Integer lineNo )
{
this
.lineNo
=
lineNo;
}
/** */
/**
* generated by Genesis
* @hibernate.property column="id" not-null="false"
*/
public
String getId ()
{
return
id;
}
/** */
/**
* generated by Genesis
*/
public
void
setId ( String id )
{
this
.id
=
id;
}
/** */
/**
Overriden toString method.
*
@return
string
*/
public
String toString()
{
return
ToStringBuilder.reflectionToString(
this
,
ToStringStyle.MULTI_LINE_STYLE);
}
/** */
/**
Overridden equals method.
*
@param
o object
*
@return
true/false
*/
public
boolean
equals(Object o)
{
return
EqualsBuilder.reflectionEquals(
this
, o);
}
/** */
/**
Creates object hash code.
*
@return
int
*/
public
int
hashCode()
{
return
HashCodeBuilder.reflectionHashCode(
this
);
}
}
关键点:主键类不要有类级别的tag ( @hibernate Class Level Tags ),主键tag为@hibernate.property.
题外话:http://www.javaeye.com/topic/1604这篇帖子提到的一些观点还是很有益的,值得看一看。
主要参考资料:
http://opensource.atlassian.com/projects/xdoclet/browse/XDT-729 bug讨论
http://www.javaeye.com/t/10182.html 该贴没有完全解决问题,
XDoclet 1: http://xdoclet.sourceforge.net/xdoclet/tags/hibernate-tags.html
http://hibernate.bluemars.net/52.html?cmd=prntdoc 提到了复合主键将在后续版本中提供(看来就是X2了),并且 is heavily under-documented,晕,到现在也没完成!
有空会研究一下X2中的composite-id怎么回事。