你有一个Hibernate实体的公共基类吗?

你有一个Hibernate实体的公共基类,即具有id,version和其他常见属性的MappedSuperclass吗? 有什么缺点吗?

例:

@MappedSuperclass() public class BaseEntity { private Long id; private Long version; ... @Id @GeneratedValue(strategy = GenerationType.AUTO) public Long getId() {return id;} public void setId(Long id) {this.id = id;} @Version public Long getVersion() {return version;} ... // Common properties @Temporal(TemporalType.TIMESTAMP) public Date creationDate() {return creationDate;} ... } @Entity public class Customer extends BaseEntity { private String customerName; ... } 

这对我们来说很好。 除了ID和创建日期,我们还有一个修改日期。 我们还有一个实现Taggable接口的中间TaggedBaseEntity ,因为我们的一些Web应用程序实体有标签,就像Stack Overflow上的问题一样。

我使用的主要是实现hashCode()和equals()。 我还添加了一个方法来打印实体。 为了响应上面的DR,大部分内容都可以被覆盖,但在我的实现中,你会遇到类型为Long的ID。

 public abstract class BaseEntity implements Serializable { public abstract Long getId(); public abstract void setId(Long id); /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((getId() == null) ? 0 : getId().hashCode()); return result; } /** * @see java.lang.Object#equals(Object) */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; BaseEntity other = (BaseEntity) obj; if (getId() == null) { if (other.getId() != null) return false; } else if (!getId().equals(other.getId())) return false; return true; } /** * @see java.lang.Object#toString() */ @Override public String toString() { return new StringBuilder(getClass().getSimpleName()).append(":").append(getId()).toString(); } /** * Prints complete information by calling all public getters on the entity. */ public String print() { final String EQUALS = "="; final String DELIMITER = ", "; final String ENTITY_FORMAT = "(id={0})"; StringBuffer sb = new StringBuffer("{"); PropertyDescriptor[] properties = PropertyUtils.getPropertyDescriptors(this); PropertyDescriptor property = null; int i = 0; while ( i < properties.length) { property = properties[i]; sb.append(property.getName()); sb.append(EQUALS); try { Object value = PropertyUtils.getProperty(this, property.getName()); if (value instanceof BaseEntity) { BaseEntity entityValue = (BaseEntity) value; String objectValueString = MessageFormat.format(ENTITY_FORMAT, entityValue.getId()); sb.append(objectValueString); } else { sb.append(value); } } catch (IllegalAccessException e) { // do nothing } catch (InvocationTargetException e) { // do nothing } catch (NoSuchMethodException e) { // do nothing } i++; if (i < properties.length) { sb.append(DELIMITER); } } sb.append("}"); return sb.toString(); } } 

我会毫不犹豫地使用一个公共基类,毕竟那是O / R映射的重点。

我也使用公共基类,但仅当实体共享至少一些公共属性时。 如果ID是唯一的共同财产,我将不会使用它。 到现在为止我没有遇到任何问题。

它也适合我。

请注意,您也可以在此实体中添加一些事件侦听器/拦截器,如Hibernate Envers,根据您的需要添加一个或任何自定义,以便您可以: – 跟踪所有修改 – 了解哪个用户进行了上次修改 – 自动更新上次修改 – 自动设置第一个插入日期和类似的东西……