项目中需要将HR模块中的表数据同步到Java系统中,向外围系统提供分发与查询服务,涉及到的表有两百多张,字段好几千上万个,如果手工一张张这些ABAP表在Java系统数据库中创建一遍的话,工作量将非常大,而且容易出错。
该ABAP代码就是将需要的表转换成Java中的实体Bean,然后就可以使用Hibernate之类的持久化框架来自动生成表了。
SPAN {
font-family: "Courier New";
font-size: 10pt;
color: #000000;
background: #FFFFFF;
}
.L0S31 {
font-style: italic;
color: #808080;
}
.L0S32 {
color: #3399FF;
}
.L0S33 {
color: #4DA619;
}
.L0S52 {
color: #0000FF;
}
.L0S55 {
color: #800080;
}
.L0S70 {
color: #808080;
}
ABAP代码没有重构过,写得有点乱......将就着看吧
font-family: "Courier New";
font-size: 10pt;
color: #000000;
background: #FFFFFF;
}
.L0S31 {
font-style: italic;
color: #808080;
}
.L0S32 {
color: #3399FF;
}
.L0S33 {
color: #4DA619;
}
.L0S52 {
color: #0000FF;
}
.L0S55 {
color: #800080;
}
.L0S70 {
color: #808080;
}
ABAP代码没有重构过,写得有点乱......将就着看吧
SPAN {
font-family: "Courier New";
font-size: 10pt;
color: #000000;
background: #FFFFFF;
}
.L0S31 {
font-style: italic;
color: #808080;
}
.L0S32 {
color: #3399FF;
}
.L0S33 {
color: #4DA619;
}
.L0S52 {
color: #0000FF;
}
.L0S55 {
color: #800080;
}
.L0S70 {
color: #808080;
}
REPORT ytab2javabean.
DATA: p_table TYPE string.
START-OF-SELECTION.
DATA: lv_path TYPE string.
lv_path = 'D:\test'.
**配置文件:以竖线分隔,第一列:SAP表名(注:SAP表名需全大写),第二列:新建表名,第三列:JavaBean名称,第四列:生成的JavaBean所在包路径
DATA: filename TYPE string VALUE 'TableCFG.txt'.
CONCATENATE lv_path `\` filename INTO filename.
TYPES: BEGIN OF itab,
fl1(300) TYPE c,
END OF itab.
DATA: data_tab TYPE STANDARD TABLE OF itab,
wa_tab LIKE LINE OF data_tab.
CALL METHOD cl_gui_frontend_services=>gui_upload
EXPORTING
filename = filename
filetype = 'ASC'
codepage = '8400'
CHANGING
data_tab = data_tab
EXCEPTIONS
file_open_error = 1
file_read_error = 2
no_batch = 3
gui_refuse_filetransfer = 4
no_authority = 6
unknown_error = 7
bad_data_format = 8
unknown_dp_error = 12
access_denied = 13
OTHERS = 17.
DATA:lt_dd03l2 TYPE TABLE OF dd03l WITH HEADER LINE.
DATA: BEGIN OF lt_dd03l OCCURS 0,
tabname TYPE dd03l-tabname,
fieldname TYPE dd03l-fieldname,
keyflag TYPE dd03l-keyflag,
rollname TYPE dd03l-rollname,
position TYPE dd03l-position,
inttype TYPE dd03l-inttype,
leng(6),
decimals(6),
ddtext TYPE dd03t-ddtext,
methodname TYPE dd03l-fieldname,
attrname TYPE dd03l-fieldname,
END OF lt_dd03l.
DATA:BEGIN OF fieldname OCCURS 0,
fieldname TYPE dd03t-fieldname ,
END OF fieldname.
DATA:BEGIN OF rollname OCCURS 0,
rollname TYPE dd04t-rollname ,
END OF rollname.
DATA:lt_dd03t TYPE TABLE OF dd03t WITH HEADER LINE,
lt_dd04t TYPE TABLE OF dd04t WITH HEADER LINE.
DATA: clsname TYPE string.
DATA: itab TYPE TABLE OF string WITH HEADER LINE.
DATA: entity TYPE string.
DATA: package TYPE string.
DATA: package_path TYPE string.
LOOP AT data_tab INTO wa_tab.
SPLIT wa_tab AT '|' INTO TABLE itab.
READ TABLE itab INDEX 1 .
p_table = itab.
READ TABLE itab INDEX 2 .
entity = itab.
READ TABLE itab INDEX 3 .
clsname = itab.
READ TABLE itab INDEX 4.
package = itab.
CONDENSE package.
package_path = package.
REPLACE `.` WITH '\' INTO package_path .
REPLACE `.` WITH '\' INTO package_path .
REPLACE `.` WITH '\' INTO package_path .
REPLACE `.` WITH '\' INTO package_path .
REPLACE `.` WITH '\' INTO package_path .
REPLACE `.` WITH '\' INTO package_path .
REPLACE `.` WITH '\' INTO package_path .
REPLACE `.` WITH '\' INTO package_path .
CLEAR: lt_dd03l, lt_dd03l[].
SELECT dd03l~tabname dd03l~fieldname keyflag rollname position inttype leng decimals FROM dd03l
INTO CORRESPONDING FIELDS OF TABLE lt_dd03l
WHERE as4local = 'A' AND dd03l~tabname = p_table AND dd03l~fieldname <> '.INCLU--AP' AND dd03l~fieldname <> '.INCLUDE' ORDER BY position.
SORT lt_dd03l BY position.
LOOP AT lt_dd03l .
IF lt_dd03l-rollname = ''.
APPEND lt_dd03l-fieldname TO fieldname.
ELSE.
APPEND lt_dd03l-rollname TO rollname.
ENDIF.
ENDLOOP.
IF fieldname[] IS NOT INITIAL.
SELECT fieldname ddtext INTO CORRESPONDING FIELDS OF TABLE lt_dd03t
FROM dd03t
FOR ALL ENTRIES IN fieldname
WHERE tabname = p_table
AND ddlanguage = '1'
AND fieldname = fieldname-fieldname.
ENDIF.
IF rollname[] IS NOT INITIAL.
SELECT rollname ddtext INTO CORRESPONDING FIELDS OF TABLE lt_dd04t
FROM dd04t
FOR ALL ENTRIES IN rollname
WHERE ddlanguage = '1'
AND rollname = rollname-rollname.
ENDIF.
DATA: i TYPE i.
FIELD-SYMBOLS <lt_dd03l> LIKE LINE OF lt_dd03l .
LOOP AT lt_dd03l ASSIGNING <lt_dd03l>.
IF <lt_dd03l>-fieldname = 'SHORT'.
<lt_dd03l>-fieldname = 'SHORT_'.
ENDIF.
i = <lt_dd03l>-leng.
<lt_dd03l>-leng = i.
i = <lt_dd03l>-decimals.
<lt_dd03l>-decimals = i.
<lt_dd03l>-methodname = <lt_dd03l>-fieldname.
* IF <lt_dd03l>-inttype = 'P' .
* <lt_dd03l>-leng = <lt_dd03l>-leng * 2 + 1.
* ENDIF.
IF <lt_dd03l>-inttype = 'I' OR <lt_dd03l>-inttype = 'X'.
<lt_dd03l>-leng = 11.
ENDIF.
TRANSLATE <lt_dd03l>-methodname TO LOWER CASE.
CONCATENATE <lt_dd03l>-fieldname+0(1) <lt_dd03l>-methodname+1 INTO <lt_dd03l>-methodname.
<lt_dd03l>-attrname = <lt_dd03l>-fieldname.
TRANSLATE <lt_dd03l>-attrname TO LOWER CASE.
REPLACE `/` WITH '_' INTO <lt_dd03l>-fieldname.
REPLACE `/` WITH '_' INTO <lt_dd03l>-fieldname.
REPLACE `/` WITH '_' INTO <lt_dd03l>-fieldname.
REPLACE `/` WITH '_' INTO <lt_dd03l>-fieldname.
READ TABLE lt_dd03t WITH KEY fieldname = <lt_dd03l>-fieldname.
IF sy-subrc = 0.
<lt_dd03l>-ddtext = lt_dd03t-ddtext.
ELSE.
READ TABLE lt_dd04t WITH KEY rollname = <lt_dd03l>-rollname.
IF sy-subrc = 0.
<lt_dd03l>-ddtext = lt_dd04t-ddtext.
ENDIF.
ENDIF.
ENDLOOP.
* LOOP AT lt_dd03l.
* WRITE:/ lt_dd03l-fieldname,lt_dd03l-keyflag,lt_dd03l-rollname,lt_dd03l-position,lt_dd03l-inttype,lt_dd03l-leng,lt_dd03l-decimals,lt_dd03l-ddtext.
* ENDLOOP.
DATA: lt_pk TYPE TABLE OF string WITH HEADER LINE.
CLEAR: lt_pk,lt_pk[].
CONCATENATE `package ` package `;` INTO lt_pk.
APPEND lt_pk.
APPEND `import java.io.Serializable;` TO lt_pk.
APPEND `import javax.persistence.Column;` TO lt_pk.
APPEND cl_abap_char_utilities=>cr_lf TO lt_pk.
CONCATENATE `public class ` clsname `Pk implements Serializable {` INTO lt_pk.
APPEND lt_pk.
APPEND `private static final long serialVersionUID = 1L;` TO lt_pk.
APPEND `private volatile int hashCode;` TO lt_pk.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
IF lt_dd03l-inttype = 'P'.
CONCATENATE `private java.math.BigDecimal ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_pk.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE `private Integer ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_pk.
ELSE.
CONCATENATE `private String ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_pk.
ENDIF.
APPEND lt_pk.
ENDLOOP.
APPEND cl_abap_char_utilities=>cr_lf TO lt_pk.
CONCATENATE `public ` clsname `Pk() { }` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `public ` clsname `Pk(` INTO lt_pk.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
IF sy-tabix = 1.
IF lt_dd03l-inttype = 'P'.
CONCATENATE lt_pk `java.math.BigDecimal ` lt_dd03l-attrname INTO lt_pk.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE lt_pk `Integer ` lt_dd03l-attrname INTO lt_pk.
ELSE.
CONCATENATE lt_pk `String ` lt_dd03l-attrname INTO lt_pk.
ENDIF.
ELSE.
IF lt_dd03l-inttype = 'P'.
CONCATENATE lt_pk `,java.math.BigDecimal ` lt_dd03l-attrname INTO lt_pk.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE lt_pk `,Integer ` lt_dd03l-attrname INTO lt_pk.
ELSE.
CONCATENATE lt_pk `,String ` lt_dd03l-attrname INTO lt_pk.
ENDIF.
ENDIF.
ENDLOOP.
CONCATENATE lt_pk `) {` INTO lt_pk.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
CONCATENATE lt_pk `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;` INTO lt_pk.
ENDLOOP.
CONCATENATE lt_pk `}` INTO lt_pk.
APPEND lt_pk.
DATA: len TYPE string.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
IF lt_dd03l-inttype = 'P'.
CONCATENATE `public java.math.BigDecimal get` lt_dd03l-methodname `() {` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `public ` clsname `Pk set` lt_dd03l-methodname `(java.math.BigDecimal ` lt_dd03l-attrname `) {`INTO lt_pk.
APPEND lt_pk.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;return this;}` INTO lt_pk.
APPEND lt_pk.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE `@Column(name = "` lt_dd03l-fieldname `", length = ` lt_dd03l-leng `)` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `public Integer get` lt_dd03l-methodname `() {` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `public ` clsname `Pk set` lt_dd03l-methodname `(Integer ` lt_dd03l-attrname `) {`INTO lt_pk.
APPEND lt_pk.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;return this;}` INTO lt_pk.
APPEND lt_pk.
ELSE.
CONCATENATE `@Column(name = "` lt_dd03l-fieldname `", length = ` lt_dd03l-leng `)` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `public String get` lt_dd03l-methodname `() {` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `public ` clsname `Pk set` lt_dd03l-methodname `(String ` lt_dd03l-attrname `) {`INTO lt_pk.
APPEND lt_pk.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;return this;}` INTO lt_pk.
APPEND lt_pk.
ENDIF.
ENDLOOP.
APPEND `@Override` TO lt_pk.
APPEND `public int hashCode() {` TO lt_pk.
APPEND `int result = hashCode;` TO lt_pk.
APPEND `if (result == 0) {` TO lt_pk.
APPEND `result = 17;` TO lt_pk.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
CONCATENATE `result = 31 * result + ((` lt_dd03l-attrname ` == null) ? 0 : ` lt_dd03l-attrname `.hashCode());` INTO lt_pk.
APPEND lt_pk.
ENDLOOP.
APPEND `hashCode = result;}return result;}` TO lt_pk.
APPEND `@Override` TO lt_pk.
APPEND `public boolean equals(Object o) {if (o == this) {return true;}` TO lt_pk.
CONCATENATE `if (!(o instanceof ` clsname `Pk)) {return false;}` INTO lt_pk.
APPEND lt_pk.
CONCATENATE clsname `Pk other = (` clsname `Pk) o;` INTO lt_pk.
APPEND lt_pk.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
CONCATENATE `if (` lt_dd03l-attrname ` == null && other.` lt_dd03l-attrname ` != null) {return false;` INTO lt_pk.
APPEND lt_pk.
CONCATENATE `} else if (` lt_dd03l-attrname ` != null &&` ` !` lt_dd03l-attrname `.equals(other.` lt_dd03l-attrname `)) {return false;}` INTO lt_pk.
APPEND lt_pk.
ENDLOOP.
* LOOP AT lt_dd03l WHERE keyflag = 'X'.
* IF sy-tabix = 1.
* CONCATENATE `return this.` lt_dd03l-attrname `.equals(other.` lt_dd03l-attrname `)` INTO lt_pk.
* APPEND lt_pk.
* ELSE.
* CONCATENATE `&& this.` lt_dd03l-attrname `.equals(other.` lt_dd03l-attrname `)` INTO lt_pk.
* APPEND lt_pk.
* ENDIF.
* ENDLOOP.
APPEND `return true;}` TO lt_pk.
APPEND `@Override` TO lt_pk.
APPEND `public String toString() {` TO lt_pk.
CONCATENATE `return "` clsname `Pk [` INTO lt_pk.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
IF sy-tabix = 1.
CONCATENATE lt_pk lt_dd03l-attrname `=" + ` lt_dd03l-attrname INTO lt_pk.
ELSE.
CONCATENATE lt_pk `+ ", ` lt_dd03l-attrname `=" + ` lt_dd03l-attrname INTO lt_pk.
ENDIF.
ENDLOOP.
CONCATENATE lt_pk `+ "]";}}` INTO lt_pk.
APPEND lt_pk.
**生成的Java实体Bean主键类
CONCATENATE lv_path `\Bean\` package_path `\` clsname `Pk.java` INTO filename.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
filename = filename
codepage = '4110'
TABLES
data_tab = lt_pk[].
"================================================================================================
DATA: lt_class TYPE TABLE OF string WITH HEADER LINE.
CLEAR: lt_class,lt_class[].
CONCATENATE `package ` package `;` INTO lt_class.
APPEND lt_class.
APPEND `import com.suning.hrqz.entity.BaseEntity;` TO lt_class.
APPEND `import javax.persistence.Column;` TO lt_class.
APPEND `import javax.persistence.Entity;` TO lt_class.
APPEND `import javax.persistence.Id;` TO lt_class.
APPEND `import javax.persistence.IdClass;` TO lt_class.
APPEND `import javax.persistence.Table;` TO lt_class.
APPEND `import javax.persistence.Transient;` TO lt_class.
CONCATENATE `//对应 SAP 表名:` p_table INTO lt_class.
APPEND lt_class.
CONCATENATE `@Entity(name = "` entity `")` INTO lt_class.
APPEND lt_class.
APPEND `@Table(` TO lt_class.
APPEND `// uniqueConstraints = { @UniqueConstraint(name="Unique_Index",columnNames = {"xx","xxx"}) }` TO lt_class.
APPEND `// ,indexes={@Index(name = "index01",columnList="xx,xxx")}` TO lt_class.
APPEND `)` TO lt_class.
CONCATENATE `@IdClass(value = ` clsname `Pk.class)` INTO lt_class.
APPEND lt_class.
CONCATENATE `public class ` clsname ` extends BaseEntity {` INTO lt_class.
APPEND lt_class.
APPEND `@Transient` TO lt_class.
APPEND `private static final long serialVersionUID = 1L;` TO lt_class.
APPEND `@Transient` TO lt_class.
CONCATENATE `private ` clsname `Pk pk;` INTO lt_class.
APPEND lt_class.
APPEND cl_abap_char_utilities=>cr_lf TO lt_pk.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
IF lt_dd03l-inttype = 'P'.
CONCATENATE `private java.math.BigDecimal ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_class.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE `private Integer ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_class.
ELSE.
CONCATENATE `private String ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_class.
ENDIF.
APPEND lt_class.
ENDLOOP.
APPEND cl_abap_char_utilities=>cr_lf TO lt_pk.
LOOP AT lt_dd03l WHERE keyflag <> 'X'.
IF lt_dd03l-inttype = 'P'.
CONCATENATE `private java.math.BigDecimal ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_class.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE `private Integer ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_class.
ELSE.
CONCATENATE `private String ` lt_dd03l-attrname `;//` lt_dd03l-ddtext INTO lt_class.
ENDIF.
APPEND lt_class.
ENDLOOP.
CONCATENATE `public ` clsname `() {` INTO lt_class.
APPEND lt_class.
CONCATENATE `pk = new ` clsname `Pk();}` INTO lt_class.
APPEND lt_class.
CONCATENATE `public ` clsname `(` INTO lt_class.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
IF sy-tabix = 1.
IF lt_dd03l-inttype = 'P'.
CONCATENATE lt_class `java.math.BigDecimal ` lt_dd03l-attrname INTO lt_class.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE lt_class `Integer ` lt_dd03l-attrname INTO lt_class.
ELSE.
CONCATENATE lt_class `String ` lt_dd03l-attrname INTO lt_class.
ENDIF.
ELSE.
IF lt_dd03l-inttype = 'P'.
CONCATENATE lt_class `,java.math.BigDecimal ` lt_dd03l-attrname INTO lt_class.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE lt_class `,Integer ` lt_dd03l-attrname INTO lt_class.
ELSE.
CONCATENATE lt_class `,String ` lt_dd03l-attrname INTO lt_class.
ENDIF.
ENDIF.
ENDLOOP.
CONCATENATE lt_class `) {` INTO lt_class.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
CONCATENATE lt_class `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;` INTO lt_class.
ENDLOOP.
APPEND lt_class.
CONCATENATE `pk = new ` clsname `Pk(` INTO lt_class.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
IF sy-tabix = 1.
CONCATENATE lt_class lt_dd03l-fieldname INTO lt_class.
ELSE.
CONCATENATE lt_class `,` lt_dd03l-fieldname INTO lt_class.
ENDIF.
ENDLOOP.
APPEND `}` TO lt_class.
APPEND cl_abap_char_utilities=>cr_lf TO lt_pk.
APPEND `@Transient` TO lt_class.
CONCATENATE `public ` clsname `Pk getPk() {return pk;}` INTO lt_class.
APPEND lt_class.
CONCATENATE `public ` clsname ` setPk(` clsname `Pk pk) {this.pk = pk;` INTO lt_class.
APPEND lt_class.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
CONCATENATE `this.` lt_dd03l-attrname ` = pk.get` lt_dd03l-methodname `();` INTO lt_class.
APPEND lt_class.
ENDLOOP.
APPEND `return this;}` TO lt_class.
LOOP AT lt_dd03l WHERE keyflag = 'X'.
APPEND `@Id` TO lt_class.
IF lt_dd03l-inttype = 'P'.
CONCATENATE `@Column(name = "` lt_dd03l-fieldname `", precision = ` lt_dd03l-leng `, scale = ` lt_dd03l-decimals `)` INTO lt_class.
APPEND lt_class.
CONCATENATE `public java.math.BigDecimal get` lt_dd03l-methodname `() {` INTO lt_class.
APPEND lt_class.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_class.
APPEND lt_class.
CONCATENATE `public ` clsname ` set` lt_dd03l-methodname `(java.math.BigDecimal ` lt_dd03l-attrname `) {`INTO lt_class.
APPEND lt_class.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;pk.set` lt_dd03l-methodname `(` lt_dd03l-attrname `);return this;}` INTO lt_class.
APPEND lt_class.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE `@Column(name = "` lt_dd03l-fieldname `", length = ` lt_dd03l-leng `)` INTO lt_class.
APPEND lt_class.
CONCATENATE `public Integer get` lt_dd03l-methodname `() {` INTO lt_class.
APPEND lt_class.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_class.
APPEND lt_class.
CONCATENATE `public ` clsname ` set` lt_dd03l-methodname `(Integer ` lt_dd03l-attrname `) {`INTO lt_class.
APPEND lt_class.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;pk.set` lt_dd03l-methodname `(` lt_dd03l-attrname `);return this;}` INTO lt_class.
APPEND lt_class.
ELSE.
CONCATENATE `@Column(name = "` lt_dd03l-fieldname `", length = ` lt_dd03l-leng `)` INTO lt_class.
APPEND lt_class.
CONCATENATE `public String get` lt_dd03l-methodname `() {` INTO lt_class.
APPEND lt_class.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_class.
APPEND lt_class.
CONCATENATE `public ` clsname ` set` lt_dd03l-methodname `(String ` lt_dd03l-attrname `) {`INTO lt_class.
APPEND lt_class.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;pk.set` lt_dd03l-methodname `(` lt_dd03l-attrname `);return this;}` INTO lt_class.
APPEND lt_class.
ENDIF.
ENDLOOP.
APPEND cl_abap_char_utilities=>cr_lf TO lt_pk.
LOOP AT lt_dd03l WHERE keyflag <> 'X'.
IF lt_dd03l-inttype = 'P'.
CONCATENATE `@Column(name = "` lt_dd03l-fieldname `", precision = ` lt_dd03l-leng `, scale = ` lt_dd03l-decimals `)` INTO lt_class.
APPEND lt_class.
CONCATENATE `public java.math.BigDecimal get` lt_dd03l-methodname `() {` INTO lt_class.
APPEND lt_class.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_class.
APPEND lt_class.
CONCATENATE `public ` clsname ` set` lt_dd03l-methodname `(java.math.BigDecimal ` lt_dd03l-attrname `) {`INTO lt_class.
APPEND lt_class.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;return this;}` INTO lt_class.
APPEND lt_class.
ELSEIF lt_dd03l-inttype = 'I' OR lt_dd03l-inttype = 'X'.
CONCATENATE `@Column(name = "` lt_dd03l-fieldname `", length = ` lt_dd03l-leng `)` INTO lt_class.
APPEND lt_class.
CONCATENATE `public Integer get` lt_dd03l-methodname `() {` INTO lt_class.
APPEND lt_class.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_class.
APPEND lt_class.
CONCATENATE `public ` clsname ` set` lt_dd03l-methodname `(Integer ` lt_dd03l-attrname `) {`INTO lt_class.
APPEND lt_class.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;return this;}` INTO lt_class.
APPEND lt_class.
ELSE.
CONCATENATE `@Column(name = "` lt_dd03l-fieldname `", length = ` lt_dd03l-leng `)` INTO lt_class.
APPEND lt_class.
CONCATENATE `public String get` lt_dd03l-methodname `() {` INTO lt_class.
APPEND lt_class.
CONCATENATE `return ` lt_dd03l-attrname `;}` INTO lt_class.
APPEND lt_class.
CONCATENATE `public ` clsname ` set` lt_dd03l-methodname `(String ` lt_dd03l-attrname `) {`INTO lt_class.
APPEND lt_class.
CONCATENATE `this.` lt_dd03l-attrname ` = ` lt_dd03l-attrname `;return this;}` INTO lt_class.
APPEND lt_class.
ENDIF.
ENDLOOP.
APPEND `@Override` TO lt_class.
APPEND `public int hashCode() {return pk.hashCode();}` TO lt_class.
APPEND `@Override` TO lt_class.
APPEND `public boolean equals(Object o) {` TO lt_class.
CONCATENATE `if (!(o instanceof ` clsname `)) {` `` INTO lt_class.
APPEND lt_class.
CONCATENATE `return false;}` clsname ` other = (` clsname `) o;` INTO lt_class.
APPEND lt_class.
* CONCATENATE `return pk.equals(new ` clsname `Pk(` INTO lt_class.
* LOOP AT lt_dd03l WHERE keyflag = 'X'.
* IF sy-tabix = 1.
* CONCATENATE lt_class `other.` lt_dd03l-attrname INTO lt_class.
* ELSE.
* CONCATENATE lt_class `,other.` lt_dd03l-attrname INTO lt_class.
* ENDIF.
* ENDLOOP.
* CONCATENATE lt_class `));}` INTO lt_class.
* APPEND lt_class.
APPEND `return pk.equals(other.getPk());}` to lt_class.
APPEND `@Override` TO lt_class.
APPEND `public String toString() {` TO lt_class.
CONCATENATE `return "` clsname ` [pk=" + pk` INTO lt_class.
LOOP AT lt_dd03l WHERE keyflag <> 'X'.
CONCATENATE lt_class `+ ", ` lt_dd03l-attrname `=" + ` lt_dd03l-attrname INTO lt_class.
ENDLOOP.
APPEND lt_class.
APPEND `+ "]";}` TO lt_class.
APPEND `}` TO lt_class.
***生成的Java实体Bean
CONCATENATE lv_path `\Bean\` package_path `\` clsname `.java` INTO filename.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
filename = filename
codepage = '4110'
TABLES
data_tab = lt_class[].
ENDLOOP.
比如要将PA0000与PA0001两个表导出,配置文件:
生成的Java实体如下:
package com.xxx;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
import javax.persistence.Transient;
//对应 SAP 表名:PA0000
@Entity(name = "HR_PA0000")
@Table(
// uniqueConstraints = { @UniqueConstraint(name="Unique_Index",columnNames =
// {"xx","xxx"}) }
// ,indexes={@Index(name = "index01",columnList="xx,xxx")}
)
@IdClass(value = Pa0000Pk.class)
public class Pa0000 extends BaseEntity {
@Transient
private static final long serialVersionUID = 1L;
@Transient
private Pa0000Pk pk;
private String mandt;// 客户端
private String pernr;// 人员号
private String subty;// 子信息类型
private String objps;// 对象标识
private String sprps;// 人力资源主数据记录的锁定标志
private String endda;// 结束日期
private String begda;// 开始日期
private String seqnr;// 相同关键值信息类型记录的编号
private String aedtm;// 更改日期
private String uname;// 对象更改人员的名称
private String histo;// 历史记录标志
private String itxex;// 信息类型的文本存在
private String refex;// 参考字段存在 (主/次级成本)
private String ordex;// 确定字段存在
private String itbld;// 信息类型屏幕控制
private String preas;// 更改主数据的原因
private String flag1;// 保留字段/未使用字段
private String flag2;// 保留字段/未使用字段
private String flag3;// 保留字段/未使用字段
private String flag4;// 保留字段/未使用字段
private String rese1;// 长度为 2 的保留字段/未使用字段
private String rese2;// 长度为 2 的保留字段/未使用字段
private String grpvl;// 关于个人分配的分组值
private String massn;// 操作类型
private String massg;// 操作原因
private String stat1;// 客户特定状态
private String stat2;// 雇佣状态
private String stat3;// 特殊支付状态
private String zsqlx;// 申请类型
public Pa0000() {
pk = new Pa0000Pk();
}
public Pa0000(String mandt, String pernr, String subty, String objps, String sprps, String endda, String begda,
String seqnr) {
this.mandt = mandt;
this.pernr = pernr;
this.subty = subty;
this.objps = objps;
this.sprps = sprps;
this.endda = endda;
this.begda = begda;
this.seqnr = seqnr;
}
@Transient
public Pa0000Pk getPk() {
return pk;
}
public Pa0000 setPk(Pa0000Pk pk) {
this.pk = pk;
this.mandt = pk.getMandt();
this.pernr = pk.getPernr();
this.subty = pk.getSubty();
this.objps = pk.getObjps();
this.sprps = pk.getSprps();
this.endda = pk.getEndda();
this.begda = pk.getBegda();
this.seqnr = pk.getSeqnr();
return this;
}
@Id
@Column(name = "MANDT", length = 3)
public String getMandt() {
return mandt;
}
public Pa0000 setMandt(String mandt) {
this.mandt = mandt;
pk.setMandt(mandt);
return this;
}
@Id
@Column(name = "PERNR", length = 8)
public String getPernr() {
return pernr;
}
public Pa0000 setPernr(String pernr) {
this.pernr = pernr;
pk.setPernr(pernr);
return this;
}
@Id
@Column(name = "SUBTY", length = 4)
public String getSubty() {
return subty;
}
public Pa0000 setSubty(String subty) {
this.subty = subty;
pk.setSubty(subty);
return this;
}
@Id
@Column(name = "OBJPS", length = 2)
public String getObjps() {
return objps;
}
public Pa0000 setObjps(String objps) {
this.objps = objps;
pk.setObjps(objps);
return this;
}
@Id
@Column(name = "SPRPS", length = 1)
public String getSprps() {
return sprps;
}
public Pa0000 setSprps(String sprps) {
this.sprps = sprps;
pk.setSprps(sprps);
return this;
}
@Id
@Column(name = "ENDDA", length = 8)
public String getEndda() {
return endda;
}
public Pa0000 setEndda(String endda) {
this.endda = endda;
pk.setEndda(endda);
return this;
}
@Id
@Column(name = "BEGDA", length = 8)
public String getBegda() {
return begda;
}
public Pa0000 setBegda(String begda) {
this.begda = begda;
pk.setBegda(begda);
return this;
}
@Id
@Column(name = "SEQNR", length = 3)
public String getSeqnr() {
return seqnr;
}
public Pa0000 setSeqnr(String seqnr) {
this.seqnr = seqnr;
pk.setSeqnr(seqnr);
return this;
}
@Column(name = "AEDTM", length = 8)
public String getAedtm() {
return aedtm;
}
public Pa0000 setAedtm(String aedtm) {
this.aedtm = aedtm;
return this;
}
@Column(name = "UNAME", length = 12)
public String getUname() {
return uname;
}
public Pa0000 setUname(String uname) {
this.uname = uname;
return this;
}
@Column(name = "HISTO", length = 1)
public String getHisto() {
return histo;
}
public Pa0000 setHisto(String histo) {
this.histo = histo;
return this;
}
@Column(name = "ITXEX", length = 1)
public String getItxex() {
return itxex;
}
public Pa0000 setItxex(String itxex) {
this.itxex = itxex;
return this;
}
@Column(name = "REFEX", length = 1)
public String getRefex() {
return refex;
}
public Pa0000 setRefex(String refex) {
this.refex = refex;
return this;
}
@Column(name = "ORDEX", length = 1)
public String getOrdex() {
return ordex;
}
public Pa0000 setOrdex(String ordex) {
this.ordex = ordex;
return this;
}
@Column(name = "ITBLD", length = 2)
public String getItbld() {
return itbld;
}
public Pa0000 setItbld(String itbld) {
this.itbld = itbld;
return this;
}
@Column(name = "PREAS", length = 2)
public String getPreas() {
return preas;
}
public Pa0000 setPreas(String preas) {
this.preas = preas;
return this;
}
@Column(name = "FLAG1", length = 1)
public String getFlag1() {
return flag1;
}
public Pa0000 setFlag1(String flag1) {
this.flag1 = flag1;
return this;
}
@Column(name = "FLAG2", length = 1)
public String getFlag2() {
return flag2;
}
public Pa0000 setFlag2(String flag2) {
this.flag2 = flag2;
return this;
}
@Column(name = "FLAG3", length = 1)
public String getFlag3() {
return flag3;
}
public Pa0000 setFlag3(String flag3) {
this.flag3 = flag3;
return this;
}
@Column(name = "FLAG4", length = 1)
public String getFlag4() {
return flag4;
}
public Pa0000 setFlag4(String flag4) {
this.flag4 = flag4;
return this;
}
@Column(name = "RESE1", length = 2)
public String getRese1() {
return rese1;
}
public Pa0000 setRese1(String rese1) {
this.rese1 = rese1;
return this;
}
@Column(name = "RESE2", length = 2)
public String getRese2() {
return rese2;
}
public Pa0000 setRese2(String rese2) {
this.rese2 = rese2;
return this;
}
@Column(name = "GRPVL", length = 4)
public String getGrpvl() {
return grpvl;
}
public Pa0000 setGrpvl(String grpvl) {
this.grpvl = grpvl;
return this;
}
@Column(name = "MASSN", length = 2)
public String getMassn() {
return massn;
}
public Pa0000 setMassn(String massn) {
this.massn = massn;
return this;
}
@Column(name = "MASSG", length = 2)
public String getMassg() {
return massg;
}
public Pa0000 setMassg(String massg) {
this.massg = massg;
return this;
}
@Column(name = "STAT1", length = 1)
public String getStat1() {
return stat1;
}
public Pa0000 setStat1(String stat1) {
this.stat1 = stat1;
return this;
}
@Column(name = "STAT2", length = 1)
public String getStat2() {
return stat2;
}
public Pa0000 setStat2(String stat2) {
this.stat2 = stat2;
return this;
}
@Column(name = "STAT3", length = 1)
public String getStat3() {
return stat3;
}
public Pa0000 setStat3(String stat3) {
this.stat3 = stat3;
return this;
}
@Column(name = "ZSQLX", length = 2)
public String getZsqlx() {
return zsqlx;
}
public Pa0000 setZsqlx(String zsqlx) {
this.zsqlx = zsqlx;
return this;
}
@Override
public int hashCode() {
return pk.hashCode();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Pa0000)) {
return false;
}
Pa0000 other = (Pa0000) o;
return pk.equals(other.getPk());
}
@Override
public String toString() {
return "Pa0000 [pk=" + pk + ", aedtm=" + aedtm + ", uname=" + uname + ", histo=" + histo + ", itxex=" + itxex
+ ", refex=" + refex + ", ordex=" + ordex + ", itbld=" + itbld + ", preas=" + preas + ", flag1=" + flag1
+ ", flag2=" + flag2 + ", flag3=" + flag3 + ", flag4=" + flag4 + ", rese1=" + rese1 + ", rese2=" + rese2
+ ", grpvl=" + grpvl + ", massn=" + massn + ", massg=" + massg + ", stat1=" + stat1 + ", stat2=" + stat2
+ ", stat3=" + stat3 + ", zsqlx=" + zsqlx + "]";
}
}
package com.xxx;
import java.io.Serializable;
import javax.persistence.Column;
public class Pa0000Pk implements Serializable {
private static final long serialVersionUID = 1L;
private volatile int hashCode;
private String mandt;// 客户端
private String pernr;// 人员号
private String subty;// 子信息类型
private String objps;// 对象标识
private String sprps;// 人力资源主数据记录的锁定标志
private String endda;// 结束日期
private String begda;// 开始日期
private String seqnr;// 相同关键值信息类型记录的编号
public Pa0000Pk() {
}
public Pa0000Pk(String mandt, String pernr, String subty, String objps, String sprps, String endda, String begda,
String seqnr) {
this.mandt = mandt;
this.pernr = pernr;
this.subty = subty;
this.objps = objps;
this.sprps = sprps;
this.endda = endda;
this.begda = begda;
this.seqnr = seqnr;
}
@Column(name = "MANDT", length = 3)
public String getMandt() {
return mandt;
}
public Pa0000Pk setMandt(String mandt) {
this.mandt = mandt;
return this;
}
@Column(name = "PERNR", length = 8)
public String getPernr() {
return pernr;
}
public Pa0000Pk setPernr(String pernr) {
this.pernr = pernr;
return this;
}
@Column(name = "SUBTY", length = 4)
public String getSubty() {
return subty;
}
public Pa0000Pk setSubty(String subty) {
this.subty = subty;
return this;
}
@Column(name = "OBJPS", length = 2)
public String getObjps() {
return objps;
}
public Pa0000Pk setObjps(String objps) {
this.objps = objps;
return this;
}
@Column(name = "SPRPS", length = 1)
public String getSprps() {
return sprps;
}
public Pa0000Pk setSprps(String sprps) {
this.sprps = sprps;
return this;
}
@Column(name = "ENDDA", length = 8)
public String getEndda() {
return endda;
}
public Pa0000Pk setEndda(String endda) {
this.endda = endda;
return this;
}
@Column(name = "BEGDA", length = 8)
public String getBegda() {
return begda;
}
public Pa0000Pk setBegda(String begda) {
this.begda = begda;
return this;
}
@Column(name = "SEQNR", length = 3)
public String getSeqnr() {
return seqnr;
}
public Pa0000Pk setSeqnr(String seqnr) {
this.seqnr = seqnr;
return this;
}
@Override
public int hashCode() {
int result = hashCode;
if (result == 0) {
result = 17;
result = 31 * result + ((mandt == null) ? 0 : mandt.hashCode());
result = 31 * result + ((pernr == null) ? 0 : pernr.hashCode());
result = 31 * result + ((subty == null) ? 0 : subty.hashCode());
result = 31 * result + ((objps == null) ? 0 : objps.hashCode());
result = 31 * result + ((sprps == null) ? 0 : sprps.hashCode());
result = 31 * result + ((endda == null) ? 0 : endda.hashCode());
result = 31 * result + ((begda == null) ? 0 : begda.hashCode());
result = 31 * result + ((seqnr == null) ? 0 : seqnr.hashCode());
hashCode = result;
}
return result;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Pa0000Pk)) {
return false;
}
Pa0000Pk other = (Pa0000Pk) o;
if (mandt == null && other.mandt != null) {
return false;
} else if (mandt != null && !mandt.equals(other.mandt)) {
return false;
}
if (pernr == null && other.pernr != null) {
return false;
} else if (pernr != null && !pernr.equals(other.pernr)) {
return false;
}
if (subty == null && other.subty != null) {
return false;
} else if (subty != null && !subty.equals(other.subty)) {
return false;
}
if (objps == null && other.objps != null) {
return false;
} else if (objps != null && !objps.equals(other.objps)) {
return false;
}
if (sprps == null && other.sprps != null) {
return false;
} else if (sprps != null && !sprps.equals(other.sprps)) {
return false;
}
if (endda == null && other.endda != null) {
return false;
} else if (endda != null && !endda.equals(other.endda)) {
return false;
}
if (begda == null && other.begda != null) {
return false;
} else if (begda != null && !begda.equals(other.begda)) {
return false;
}
if (seqnr == null && other.seqnr != null) {
return false;
} else if (seqnr != null && !seqnr.equals(other.seqnr)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Pa0000Pk [mandt=" + mandt + ", pernr=" + pernr + ", subty=" + subty + ", objps=" + objps + ", sprps="
+ sprps + ", endda=" + endda + ", begda=" + begda + ", seqnr=" + seqnr + "]";
}
}
上面是PA0000这个表所生成的实体Bean,每张会生成两个类,PK结尾的是主键,另一个是非主键Bean。另外,除了ABAP表的字段外,可能还需扩展几个字段,这些扩展字段可以放在 BaseEntity 父类里:
package com.xxx;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
@MappedSuperclass
public class BaseEntity implements Serializable {
@Transient
private static final long serialVersionUID = 1L;
@Transient
private String module;// 表所属模块
@Transient
private String tableName;// 表名
private String insertTime;// 数据插入时间
private String lastUpdateTime;// 数据最后一次更新时间
private String deleteFlg;// 是否被删除了
@Column(length = 14, name = "INSERT_TIME", updatable = false)
public String getInsertTime() {
return insertTime;
}
public void setInsertTime(String insertTime) {
this.insertTime = insertTime;
}
@Column(length = 14, name = "LAST_UPDATE_TIME")
public String getLastUpdateTime() {
return lastUpdateTime;
}
public void setLastUpdateTime(String lastUpdateTime) {
this.lastUpdateTime = lastUpdateTime;
}
@Column(length = 1, name = "DELETE_FLG")
public String getDeleteFlg() {
return deleteFlg;
}
public void setDeleteFlg(String deleteFlg) {
this.deleteFlg = deleteFlg;
}
@Transient
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
@Transient
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
}
生成这些实体Bean类后,然后使用Hibernate持久化框架就可以自动生成表了,这里不再演示,做过Java Web开发的都知道,Easy.....不过要注意的是,Hibernate根据实体类生成表时,发现字段顺序与实体Bean中定义的字段顺序不一样,这也就与ABAP表字段顺序不一样了,这是Hibernate的问题,可以修改Hibernate里相应Jar包里这个类,并将它替换掉即可:
注意Hibernate版本是4.3.8的,下面是经过修改后的类,编译后替换原Jar包中相应的类即可:
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
// $Id$
package org.hibernate.cfg;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.persistence.Access;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
import org.hibernate.annotations.ManyToAny;
import org.hibernate.annotations.Target;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.jboss.logging.Logger;
/**
* A helper class to keep the {@code XProperty}s of a class ordered by access
* type.
*
* @author Hardy Ferentschik
*/
class PropertyContainer {
static {
System.setProperty("jboss.i18n.generate-proxies", "true");
}
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class,
PropertyContainer.class.getName());
private final AccessType explicitClassDefinedAccessType;
/**
* Constains the properties which must be returned in case the class is accessed
* via {@code AccessType.FIELD}. Note, this does not mean that all
* {@code XProperty}s in this map are fields. Due to JPA access rules single
* properties can have different access type than the overall class access type.
*/
private final LinkedHashMap<String, XProperty> fieldAccessMap;
/**
* Constains the properties which must be returned in case the class is accessed
* via {@code AccessType.Property}. Note, this does not mean that all
* {@code XProperty}s in this map are properties/methods. Due to JPA access
* rules single properties can have different access type than the overall class
* access type.
*/
private final LinkedHashMap<String, XProperty> propertyAccessMap;
private static LinkedHashMap<String, XProperty> fieldAccessMapBase;
private static LinkedHashMap<String, XProperty> propertyAccessMapBase;
/**
* The class for which this container is created.
*/
private final XClass xClass;
private final XClass entityAtStake;
PropertyContainer(XClass clazz, XClass entityAtStake) {
this.xClass = clazz;
this.entityAtStake = entityAtStake;
explicitClassDefinedAccessType = determineClassDefinedAccessStrategy();
// first add all properties to field and property map
if (xClass.getName().toLowerCase().endsWith("baseentity")) {
if (fieldAccessMapBase == null) {
fieldAccessMapBase = initProperties(AccessType.FIELD);
propertyAccessMapBase = initProperties(AccessType.PROPERTY);
}
fieldAccessMap = new LinkedHashMap<String, XProperty>();
propertyAccessMap = new LinkedHashMap<String, XProperty>();
} else {
fieldAccessMap = initProperties(AccessType.FIELD);
propertyAccessMap = initProperties(AccessType.PROPERTY);
}
considerExplicitFieldAndPropertyAccess();
}
public XClass getEntityAtStake() {
return entityAtStake;
}
public XClass getDeclaringClass() {
return xClass;
}
public AccessType getExplicitAccessStrategy() {
return explicitClassDefinedAccessType;
}
public boolean hasExplicitAccessStrategy() {
return !explicitClassDefinedAccessType.equals(AccessType.DEFAULT);
}
public Collection<XProperty> getProperties(AccessType accessType) {
assertTypesAreResolvable(accessType);
if (AccessType.DEFAULT == accessType || AccessType.PROPERTY == accessType) {
return Collections.unmodifiableCollection(propertyAccessMap.values());
} else {
return Collections.unmodifiableCollection(fieldAccessMap.values());
}
}
private void assertTypesAreResolvable(AccessType access) {
Map<String, XProperty> xprops;
if (AccessType.PROPERTY.equals(access) || AccessType.DEFAULT.equals(access)) {
xprops = propertyAccessMap;
} else {
xprops = fieldAccessMap;
}
for (XProperty property : xprops.values()) {
if (!property.isTypeResolved() && !discoverTypeWithoutReflection(property)) {
String msg = "Property " + StringHelper.qualify(xClass.getName(), property.getName())
+ " has an unbound type and no explicit target entity. Resolve this Generic usage issue"
+ " or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type";
throw new AnnotationException(msg);
}
}
}
private void considerExplicitFieldAndPropertyAccess() {
for (XProperty property : fieldAccessMap.values()) {
Access access = property.getAnnotation(Access.class);
if (access == null) {
continue;
}
// see "2.3.2 Explicit Access Type" of JPA 2 spec
// the access type for this property is explicitly set to
// AccessType.FIELD, hence we have to
// use field access for this property even if the default access
// type for the class is AccessType.PROPERTY
AccessType accessType = AccessType.getAccessStrategy(access.value());
if (accessType == AccessType.FIELD) {
propertyAccessMap.put(property.getName(), property);
System.out.println("considerExplicitFieldAndPropertyAccess=propertyAccessMap========"
+ property.getName() + "--" + property);
} else {
LOG.debug("Placing @Access(AccessType.FIELD) on a field does not have any effect.");
}
}
for (XProperty property : propertyAccessMap.values()) {
Access access = property.getAnnotation(Access.class);
if (access == null) {
continue;
}
AccessType accessType = AccessType.getAccessStrategy(access.value());
// see "2.3.2 Explicit Access Type" of JPA 2 spec
// the access type for this property is explicitly set to
// AccessType.PROPERTY, hence we have to
// return use method access even if the default class access type is
// AccessType.FIELD
if (accessType == AccessType.PROPERTY) {
fieldAccessMap.put(property.getName(), property);
System.out.println("considerExplicitFieldAndPropertyAccess=fieldAccessMap========" + property.getName()
+ "--" + property);
} else {
LOG.debug("Placing @Access(AccessType.PROPERTY) on a field does not have any effect.");
}
}
}
/**
* Retrieves all properties from the {@code xClass} with the specified access
* type. This method does not take any jpa access rules/annotations into account
* yet.
*
* @param access
* The access type - {@code AccessType.FIELD} or
* {@code AccessType.Property}
*
* @return A maps of the properties with the given access type keyed against
* their property name
*/
private LinkedHashMap<String, XProperty> initProperties(AccessType access) {
if (!(AccessType.PROPERTY.equals(access) || AccessType.FIELD.equals(access))) {
throw new IllegalArgumentException("Access type has to be AccessType.FIELD or AccessType.Property");
}
// order so that property are used in the same order when binding native
// query
LinkedHashMap<String, XProperty> propertiesMap = new LinkedHashMap<String, XProperty>();
List<XProperty> properties = xClass.getDeclaredProperties(access.getType());
List<XProperty> properties2 = xClass.getDeclaredProperties(AccessType.FIELD.getType());
List<XProperty> propertiess = new LinkedList<XProperty>();
for (Iterator<XProperty> iterator = properties2.iterator(); iterator.hasNext();) {
XProperty xProperty = (XProperty) iterator.next();
for (Iterator<XProperty> iterator2 = properties.iterator(); iterator2.hasNext();) {
XProperty xProperty2 = (XProperty) iterator2.next();
if (xProperty.getName().equals(xProperty2.getName())) {
propertiess.add(xProperty2);
break;
}
}
}
properties = propertiess;
for (XProperty property : properties) {
if (mustBeSkipped(property)) {
continue;
}
propertiesMap.put(property.getName(), property);
}
if (!xClass.getName().toLowerCase().endsWith("baseentity") && !xClass.getName().toLowerCase().endsWith("_pk")
&& !xClass.getName().toLowerCase().endsWith("pk")) {
if (AccessType.FIELD.equals(access)) {
propertiesMap.putAll(fieldAccessMapBase);
} else {
propertiesMap.putAll(propertyAccessMapBase);
}
}
return propertiesMap;
}
private AccessType determineClassDefinedAccessStrategy() {
AccessType classDefinedAccessType;
AccessType hibernateDefinedAccessType = AccessType.DEFAULT;
AccessType jpaDefinedAccessType = AccessType.DEFAULT;
org.hibernate.annotations.AccessType accessType = xClass
.getAnnotation(org.hibernate.annotations.AccessType.class);
if (accessType != null) {
hibernateDefinedAccessType = AccessType.getAccessStrategy(accessType.value());
}
Access access = xClass.getAnnotation(Access.class);
if (access != null) {
jpaDefinedAccessType = AccessType.getAccessStrategy(access.value());
}
if (hibernateDefinedAccessType != AccessType.DEFAULT && jpaDefinedAccessType != AccessType.DEFAULT
&& hibernateDefinedAccessType != jpaDefinedAccessType) {
throw new MappingException(
"@AccessType and @Access specified with contradicting values. Use of @Access only is recommended. ");
}
if (hibernateDefinedAccessType != AccessType.DEFAULT) {
classDefinedAccessType = hibernateDefinedAccessType;
} else {
classDefinedAccessType = jpaDefinedAccessType;
}
return classDefinedAccessType;
}
private static boolean discoverTypeWithoutReflection(XProperty p) {
if (p.isAnnotationPresent(OneToOne.class)
&& !p.getAnnotation(OneToOne.class).targetEntity().equals(void.class)) {
return true;
} else if (p.isAnnotationPresent(OneToMany.class)
&& !p.getAnnotation(OneToMany.class).targetEntity().equals(void.class)) {
return true;
} else if (p.isAnnotationPresent(ManyToOne.class)
&& !p.getAnnotation(ManyToOne.class).targetEntity().equals(void.class)) {
return true;
} else if (p.isAnnotationPresent(ManyToMany.class)
&& !p.getAnnotation(ManyToMany.class).targetEntity().equals(void.class)) {
return true;
} else if (p.isAnnotationPresent(org.hibernate.annotations.Any.class)) {
return true;
} else if (p.isAnnotationPresent(ManyToAny.class)) {
if (!p.isCollection() && !p.isArray()) {
throw new AnnotationException("@ManyToAny used on a non collection non array property: " + p.getName());
}
return true;
} else if (p.isAnnotationPresent(Type.class)) {
return true;
} else if (p.isAnnotationPresent(Target.class)) {
return true;
}
return false;
}
private static boolean mustBeSkipped(XProperty property) {
// TODO make those hardcoded tests more portable (through the bytecode
// provider?)
return property.isAnnotationPresent(Transient.class)
|| "net.sf.cglib.transform.impl.InterceptFieldCallback".equals(property.getType().getName())
|| "org.hibernate.bytecode.internal.javassist.FieldHandler".equals(property.getType().getName());
}
}