I'm having some problems with inheritance and the @PrePersist annotation. My source code looks like the following:
_the 'base' class with the annotated updateDates() method:
@javax.persistence.Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Base implements Serializable{
...
开发者_如何学Go @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();
}
}
_ now the 'Child' class that should inherit all methods "and annotations" from the base class:
@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
...
}
If I store/persist instances of the Base class to the database, everything works fine. The dates are getting updated. But now, if I want to persist a child instance, the database throws the following exception:
MySQLIntegrityConstraintViolationException: Column 'CREATIONDATE' cannot be null
So, in my opinion, this is caused because in Child the method "@PrePersist protected void updateDates()" is not called/invoked before persisting the instances to the database.
What is wrong with my code?
I've tested your code with Hibernate as JPA provider (and HSQLDB). I just made the following change in the base class (because you can't use IDENTIY
- the default with HSQLDB and also with MySQL if I'm not wrong - with a TABLE_PER_CLASS
strategy1):
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
protected Long id;
With this change, the following test method passes:
@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());
}
So the @PrePersist
annotated method gets called in the inherited class.
This begs the question: which JPA provider do you use?
1 see this thread for background on this.
精彩评论