Java JPA Hibernate Spring @EntityListeners throws org.springframework.dao.DataIntegrityViolationException
- by user
I am using Spring 3 with Hibernate 3. I would like to update the last modification date automatically when an entity is updated. Below is the sample code:
HibernateConfig:
@Configuration
public class HibernateConfig {
    @Bean
    public DataSource dataSource() throws Exception {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        Properties properties = new Properties();
        properties.load(ClassLoader.getSystemResourceAsStream(new String("hibernate.properties")));
        dataSource.setUrl(properties.getProperty(new String("jdbc.url")));
        dataSource.setUsername(properties.getProperty(new String("jdbc.username")));
        dataSource.setPassword(properties.getProperty(new String("jdbc.password")));
        dataSource.setDriverClassName(properties.getProperty(new String("jdbc.driverClassName")));
        return dataSource;
    }
    @Bean
    public AnnotationSessionFactoryBean sessionFactory() throws Exception {
        AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();
        Properties hibernateProperties = new Properties();
        Properties properties = new Properties();
        properties.load(ClassLoader.getSystemResourceAsStream(new String("hibernate.properties")));
        // set the Hibernate Properties
        hibernateProperties.setProperty(new String("hibernate.dialect"), properties.getProperty(new String("hibernate.dialect")));
        hibernateProperties.setProperty(new String("hibernate.show_sql"), properties.getProperty(new String("hibernate.show_sql")));
        hibernateProperties.setProperty(new String("hibernate.hbm2ddl.auto"), properties.getProperty(new String("hibernate.hbm2ddl.auto")));
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setHibernateProperties(hibernateProperties);
        sessionFactory.setAnnotatedClasses(new Class[]{Message.class})
        return sessionFactory;
    }
    @Bean
    public HibernateTemplate hibernateTemplate() throws Exception {
        HibernateTemplate hibernateTemplate = new HibernateTemplate();
        hibernateTemplate.setSessionFactory(sessionFactory().getObject());
        return hibernateTemplate;
    }
}
DAOConfig:
@Configuration
public class DAOConfig {
    @Autowired
    private HibernateConfig hibernateConfig;
    @Bean
    public MessageDAO messageDAO() throws Exception {
        MessageDAO messageDAO = new MessageHibernateDAO(hibernateConfig.hibernateTemplate());
        return messageDAO;
    }
}
Message:
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
@Table
@EntityListeners(value = MessageListener.class)
public class Message implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column
    private int id;
    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastMod;
    public Message() {
    }
    public int getId() {
       return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public Date getLastMod() {
        return lastMod;
    }
    public void setLastMod(Date lastMod) {
        this.lastMod = lastMod;
    }
}
MessageListener:
import java.util.Date;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import org.springframework.stereotype.Component;
@Component
public class MessageListener {
    @PrePersist
    @PreUpdate
    public void setLastMod(Message message) {
        message.setLastMod(new Date());
    }
}
When running this the MessageListener is not being invoked. I use a DAO design pattern and when calling dao.update(Message) it throws the following Exception:
org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: com.persistence.entities.MessageStatus.lastMod; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: com.persistence.entities.Message.lastMod
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:665)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:683)
at com.persistence.dao.hibernate.GenericHibernateDAO.save(GenericHibernateDAO.java:38)
Having looked at a number of websites there seems not to be a solution.