2010-03-31 20 views
7

Tengo algunos problemas con la herencia y la anotación @PrePersist. Mi código fuente tiene el siguiente aspecto:@PrePersist with entity inheritance

_la clase 'base' con los updateDates anotados() Método:

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

_ ahora la clase 'niño' que debe heredar todos los métodos "y anotaciones " de la clase base:

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

Si almaceno/persisto instancias de la clase base a la base de datos, todo funciona bien. Las fechas se están actualizando. Pero ahora, si quiero que persista una instancia secundaria, la base de datos arroja la siguiente excepción:

MySQLIntegrityConstraintViolationException: Column 'CREATIONDATE' cannot be null 

Por lo tanto, en mi opinión, esto es causado debido a que en el método del niño "@PrePersist updateDates protected void()" no se llama/invoca antes de persistir las instancias a la base de datos.

¿Qué problema tiene mi código?

Respuesta

5

He probado su código con Hibernate como proveedor JPA (y HSQLDB). Acabo de hacer el siguiente cambio en la clase base (porque no se puede utilizar IDENTIY - el valor por defecto con HSQLDB y también con MySQL si no estoy equivocado - con una estrategia TABLE_PER_CLASS):

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

con este cambio, el siguiente método de ensayo pasa:

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

Así el método anotado @PrePersist se llama en la clase heredada.

Esto plantea la pregunta: ¿qué proveedor de JPA usas?

ver this thread para obtener más información sobre esto.