目标:hibernate的所有实体类的主键均继承一个基类IdEntity,基类如下:
/** * 统一定义id的entity基类. * @author MingDao */ // JPA基类标识 @MappedSuperclass public abstract class IdEntity { protected Long id; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
这样统一定义所有的派生类主键的属性名称、数据类型、列名映射和生成策略。
在实体类的数据表主键字段名称也为“id”的情况下,可以派生自IdEntity。这种情况下的派生类如下:
/** * 系统用户实体 */ @Entity @Table(name = "SYS_USER") public class User extends IdEntity { private String name; private String account; private String password; @Column(name = "USER_NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @Column(name = "USER_ACCOUNT") public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } @Column(name = "USER_PASSWORD") public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
这张数据表拥有id,user_name,user_account,user_password几个字段。
通过hibernate查询时输出的类似SQL为:SELECT id,user_name,user_account,user_password FROM sys_user。
但是如果实体类的数据表主键字段名称不是“id”的话,就没有办法使用主键基类了。
尝试过在派生类中重写基类的getId函数,并重新定义主键列名映射,结果会导致操作数据表时多出一个id列,并出错。
尝试过的实体类如下:
/** * 客户类型实体类 */ @Entity @Table(name="HHS_CLIENTTYPE") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class ClientType extends IdEntity implements Serializable { private static final long serialVersionUID = 4005802016130232896L; private String clntpCode; //客户类别编码 private String clntpName; //客户类别名称 @Id @Column(name="CLNTP_ID") @Override public Long getId() { return super.getId(); } @Column(name="CLNTP_CODE") public String getClntpCode() { return clntpCode; } public void setClntpCode(String clntpCode) { this.clntpCode = clntpCode; } @Column(name="CLNTP_NAME") public String getClntpName() { return clntpName; } public void setClntpName(String clntpName) { this.clntpName = clntpName; } }
这张数据表拥有clntp_id,clntp_code,clntp_name几个字段。clntp_id为主键。
现在通过hibernate查询时输出的类似SQL为:SELECT clntp_id,id,clntp_code,clntp_name FROM hhs_clientType。
多出一个id字段,导致抛出SQL异常错误。
因为这张表是原系统中已经存在的,所以表结构没有办法修改。
并且,实体类也要求需要继承自IdEntity基类,是因为在其它地方有工具需要使用。
基类IdEntity是参考了springSide的做法,并且springSide在IdEntity中也注释声称可以在派生类中重写getId()函数重定义id的列名映射和生成策略.
解决方案:在派生类上添加修改注解和对应列名@AttributeOverride( name="id", column = @Column(name="fld_altitude") )重写id的注解定义.