具有实体继承的@PrePersist

时间:2010-03-31 11:59:44

标签: inheritance jpa

我在继承和 @PrePersist 注释方面遇到了一些问题。 我的源代码如下所示:

_带有注释updateDates()方法的'base'类:

@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();
    }
}

_现在应该从基类继承所有方法 “和注释” 的'Child'类:

@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
    ...
}

如果我将Base类的实例存储/持久化到数据库,一切正常。日期正在更新。 但是现在,如果我想要持久保存子实例,则数据库会抛出以下异常:

MySQLIntegrityConstraintViolationException: Column 'CREATIONDATE' cannot be null

因此,在我看来,这是因为在Child中,在将实例持久保存到数据库之前,不调用/调用方法“@PrePersist protected void updateDates()”。

我的代码出了什么问题?

1 个答案:

答案 0 :(得分:5)

我已经使用Hibernate作为JPA提供程序(和HSQLDB)测试了您的代码。我刚刚在基类中进行了以下更改(因为你不能使用IDENTIY - 默认使用HSQLDB,如果我没有错误也使用MySQL - 使用TABLE_PER_CLASS策略 1 ):

@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提供商?

1 请参阅this thread了解相关背景。