hibernate+jpa中的组合主键与系统表的实体映射
关于hibernate中的组合主键,相信很多人都已经很清楚了。
建立对应的ID实体并实现Serializable接口,在目标实体中加入ID对象并注解Id或EmbeddedId(具体可自行查阅)。
最近在项目实施中查阅资料时,发现注解EmbeddedId的解释:使用EmbeddedId注解时,只能有一个EmbeddedId注解且没有Id注解。反向思考使用Id注解时是不是可以存在多个Id注解且没有使用EmbeddedId注解。
使用hibernate保存实体时,可能会遇到一个错误:session已经存在了一个相同id的实体。这就是需要组合主键的地方,数据表可以不设置主键,实体却必须指定主键,hibernate在session中便是根据实体设置的主键来确定唯一对象。
既然这样,尝试一下:
@Id
@Column(name = "CZ_TAB_ID")
private String czTabId;
@Id
@Column(name = "CZ_TAB_NAME")
private String czTabName;
@Column(name = "CZ_TAB_COMMENT")
private String czTabComment;
@Column(name = "CZ_TAB_ORDER")
private int czTabOrder;
没错,完全可行。
好处也显而易见,不仅仅是少写一个id对象而已,使用过id对象的都能理解,复合主键的实体类必须重写equals和hashCode方法。单一主键时hibernate会帮我们比对对象,使用组合主键则需要程序员重写这些方法来比对对象。如果使用jpa工具直接对应表生成还好,如果自己手写实体,或者数据表主键设计不完善与业务需求的主键不一样就麻烦了。
下面是第二点,对系统表建立实体映射,经过上面的多Id注解以后我感觉可能hibernate并不是太严格,于是尝试了映射系统表对象。
@Entity
@Table(name = "ALL_TAB_COMMENTS")
public class AllTabComments implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column
private String owner;
@Id
@Column(name = "TABLE_NAME")
private String tableName;
@Column(name = "TABLE_TYPE")
private String tableType;
@Column
private String comments;
get/set...
}
也是完全没问题,至于其它的系统表能否映射我就不管了,反正我用到的可以。^_^/