使用   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怎么回事。