2010-03-31 78 views
7

我在繼承和@PrePersist註釋有一些問題。 我的源代碼如下所示:@PrePersist與實體繼承

_The「基地」類的註解updateDates()方法:

@javax.persistence.Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public class Base implements Serializable{ 

    ... 

    @Id 
    @GeneratedValue 
    protected Long id; 
    ... 
    @Column(nullable=false) 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date creationDate; 
    @Column(nullable=false) 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date lastModificationDate; 
    ... 
    public Date getCreationDate() { 
     return creationDate; 
    } 
    public void setCreationDate(Date creationDate) { 
     this.creationDate = creationDate; 
    } 
    public Date getLastModificationDate() { 
     return lastModificationDate; 
    } 
    public void setLastModificationDate(Date lastModificationDate) { 
     this.lastModificationDate = lastModificationDate; 
    } 
    ... 
    @PrePersist 
    protected void updateDates() { 
     if (creationDate == null) { 
     creationDate = new Date(); 
     } 
     lastModificationDate = new Date(); 
    } 
} 

_現在「兒童」類,要繼承所有方法「和註釋「從基類:

@javax.persistence.Entity 
@NamedQueries({ 
    @NamedQuery(name=Sensor.QUERY_FIND_ALL, query="SELECT s FROM Sensor s") 
}) 
public class Sensor extends Entity { 
    ... 
    // additional attributes 
    @Column(nullable=false) 
    protected String value; 
    ... 
    // additional getters, setters 
    ... 
} 

如果我保存/持續的基類的實例到數據庫中,一切工作正常。日期正在更新。 但現在,如果我想堅持一個子實例,數據庫拋出以下異常:

MySQLIntegrityConstraintViolationException: Column 'CREATIONDATE' cannot be null 

所以,在我看來,這是因爲兒童造成法「@PrePersist保護無效updateDates()」在將實例持久化到數據庫之前不會調用/調用。

我的代碼有什麼問題?

回答

5

我已經用Hibernate測試了你的代碼作爲JPA提供者(和HSQLDB)。我只是做了在基類中的以下變化(因爲你不能使用IDENTIY - 如果我沒有錯HSQLDB默認值,也與MySQL - 用TABLE_PER_CLASS戰略):

@Id 
@GeneratedValue(strategy = GenerationType.TABLE) 
protected Long id; 

隨着這一變化,下面的測試方法傳遞:

@Test 
public void test_Insert_EntityWithInheritedPrePersist() { 
    EntityWithInheritedPrePersist child = new EntityWithInheritedPrePersist(); 
    child.setValue("test"); 
    entityManager.persist(child); 

    assertEquals(child.getId(), Long.valueOf(1l)); 
    assertNotNull(child.getCreationDate()); 
    assertNotNull(child.getLastModificationDate()); 
} 

所以@PrePersist註解的方法被調用的繼承類。

這引出了一個問題:您使用哪個JPA提供程序?

請參閱this thread爲此背景。