2008-10-01 79 views
20

您是否擁有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; 
    ... 
} 

回答

4

這工作得很好了我們。除了ID和創建日期,我們還有修改日期。我們也有一箇中間的TaggedBaseEntity,它實現了一個接口,因爲我們的一些Web應用程序的實體有標籤,就像Stack Overflow的問題一樣。

1

畢竟這是O/R映射的重點,我會毫不猶豫地使用一個通用基類。

我也使用公共基類,但只有當實體共享至少一些共同的屬性。如果身份證是唯一的共同財產,我不會使用它。直到現在我沒有遇到任何問題。

5

我使用的主要是實現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

0

找到一些樣品它非常適合我。

請注意,您還可以在這個實體添加一些事件監聽器/攔截器就像休眠Envers一個或根據您的需要,讓您可以在任何自定義的: - 跟蹤所有修改 - 知道哪些用戶的最後一次修改 - 自動更新最後修改 - 自動設置第一個插入日期 和療法類似的東西...

相關問題