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

问题描述:

您是否拥有Hibernate实体的公共基类,即具有id,版本和其他常用属性的MappedSuperclass?有什么缺点吗?你有一个Hibernate实体的公共基类吗?

例子:

@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和创建日期,我们还有修改日期。我们也有一个中间的TaggedBaseEntity,它实现了一个接口,因为我们的一些Web应用程序的实体有标签,就像Stack Overflow的问题一样。

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

我也使用公共基类,但只有当实体共享至少一些共同的属性。如果身份证是唯一的共同财产,我不会使用它。直到现在我没有遇到任何问题。

我使用的主要是实现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(); 
    } 
} 
+0

对不起,你为什么要使用一个while循环什么似乎更适合在一个for循环? – 2009-01-29 15:42:54

找到一些样品它非常适合我。

请注意,您还可以在这个实体添加一些事件监听器/拦截器就像休眠Envers一个或根据您的需要,让您可以在任何自定义的: - 跟踪所有修改 - 知道哪些用户的最后一次修改 - 自动更新最后修改 - 自动设置第一个插入日期 和疗法类似的东西...