首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java JPA Hibernate Spring @EntityListeners抛出org.springframework.dao.DataIntegrityViolationException

Java JPA Hibernate Spring @EntityListeners抛出org.springframework.dao.DataIntegrityViolationException
EN

Stack Overflow用户
提问于 2014-08-19 17:35:44
回答 2查看 1.7K关注 0票数 0

我正在使用Spring 3和Hibernate 3。我想在更新实体时自动更新上次修改日期。以下是示例代码:

HibernateConfig:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
@Configuration
public class DAOConfig {

    @Autowired
    private HibernateConfig hibernateConfig;

    @Bean
    public MessageDAO messageDAO() throws Exception {
        MessageDAO messageDAO = new MessageHibernateDAO(hibernateConfig.hibernateTemplate());
        return messageDAO;
    }
}

消息:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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());
    }
}

运行此命令时,不会调用MessageListener。我使用DAO设计模式,当调用dao.update(消息)时,它抛出以下异常:

代码语言:javascript
复制
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)

在查看了许多网站后,似乎没有一个解决方案。

EN

回答 2

Stack Overflow用户

发布于 2014-08-19 17:55:46

您似乎没有使用EntityManager,相当简单的Hibernate SessionFactory。另一个答案Hibernate/JPA - Entity listener not being called properly似乎表明,如果不手动设置侦听器,这将无法工作。

票数 1
EN

Stack Overflow用户

发布于 2014-08-19 18:17:55

为了让JPA侦听器使用SessionFactory处理Hibernate,从而能够使用注释(@PostPersist@PostUpdate,...),我必须使用JPAIntegrator类做以下难看的事情。

这是我的Spring bean:

代码语言:javascript
复制
@Autowired
private LocalSessionFactoryBean sessionFactoryBean;

@PostConstruct
public void init() throws ClassNotFoundException {
    SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) sessionFactoryBean.getObject();
    SessionFactoryServiceRegistry serviceRegistry = (SessionFactoryServiceRegistry)sessionFactory.getServiceRegistry();

    Configuration configuration = sessionFactoryBean.getConfiguration();

    new JpaIntegrator().integrate(configuration, sessionFactory, serviceRegistry);
}

如果只是为了让日期字段保持更新,那么您应该看看JPA @Version annotation。它的主要目的是提供乐观锁定来管理对数据的并发更新。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25380101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档