我在继承和@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();
}
}
Run Code Online (Sandbox Code Playgroud)
_现在应该继承基类中所有方法"和注释"的'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
...
}
Run Code Online (Sandbox Code Playgroud)
如果我将Base类的实例存储/持久化到数据库,一切正常.日期正在更新.但是现在,如果我想要持久保存子实例,则数据库会抛出以下异常:
MySQLIntegrityConstraintViolationException: Column 'CREATIONDATE' cannot be null
Run Code Online (Sandbox Code Playgroud)
所以,在我看来,这是因为在Child中,在将实例持久化到数据库之前,不调用/调用方法"@PrePersist protected void updateDates()".
我的代码出了什么问题?
我用Hibernate作为JPA提供程序(和HSQLDB)测试了你的代码.我只是在基类中进行了以下更改(因为你不能使用IDENTIY- 默认使用HSQLDB,如果我没有错误也使用MySQL - 使用TABLE_PER_CLASS策略1):
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
protected Long id;
Run Code Online (Sandbox Code Playgroud)
通过此更改,以下测试方法通过:
@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());
}
Run Code Online (Sandbox Code Playgroud)
因此@PrePersist,在继承的类中调用带注释的方法.
这引出了一个问题:你使用哪个JPA提供商?