休眠中的PreInsert和PreUpdate事件监听器

发布于 2021-02-01 12:26:03

我已经使用PreInsertEventListenerPreUpdateEventListener事件监听器插入创建日期和表更新的日期。
我面临的问题是,当我将实体保存在数据库中的创建日期无法与在更新记录时插入更新日期相同的表中插入时,它也不会插入更新日期。

我的代码示例如下所示:

侦听器类别:

public class PreInsertListener implements PreInsertEventListener,  
                                          PreUpdateEventListener 
{
    @Override
    public boolean onPreInsert(PreInsertEvent arg0) {
        City.class.cast(arg0.getEntity()).setCreated_date(new Date());
        return false;
    }

    @Override
    public boolean onPreUpdate(PreUpdateEvent arg0) {
        System.out.println("Update event......");
        City.class.cast(arg0.getEntity()).setUpdated_date(new Date());
        return false;
    }
}

hibernate连接类:

public class HibernateUtil 
{

    private static final SessionFactory sessionFactory;

    static {
        try {
            AnnotationConfiguration config = new AnnotationConfiguration();
            config.setListener("pre-insert", new PreInsertListener());
            config.setListener("pre-update", new PreInsertListener());
            sessionFactory = config.configure().buildSessionFactory();;

        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

DAO中的实体保存和更新方法:

public Long saveCity(String cityName)
{
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction transaction = null;
    Long cityId = null;
    try {
        transaction = session.beginTransaction();
        City city = new City();
        city.setName(cityName);
        cityId = (Long) session.save(city);
        //session.flush();
        transaction.commit();
    } catch (HibernateException e) {
        transaction.rollback();
        e.printStackTrace();
    } finally {
        session.close();
    }
    return cityId;
}

public void updateCity(Long cityId, String cityName)
{
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction transaction = null;
    try {
        transaction = session.beginTransaction();
        City city = (City) session.get(City.class, cityId);
        city.setName(cityName);
        session.update(city);
        //session.flush();
        transaction.commit();
    } catch (HibernateException e) {
        transaction.rollback();
        e.printStackTrace();
    } finally {
        session.close();
    }
}

我的测试班:

public class Main 
{
    public static void main(String[] args) {

        CityDAO cityDAO = new CityDAO();

        long cityId1 = cityDAO.saveCity("New York");

        cityDAO.updateCity(cityId1, "Paris");
    }
 }

如果我使用的session.flush()话,它将插入创建和更新的日期,但是每次我调用flush方法时都会执行更新的查询。目前,我评论了代码来调用session.flush()方法,如代码所示。

这个问题有什么解决方案?

关注者
0
被浏览
106
1 个回答
  • 面试哥
    面试哥 2021-02-01
    为面试而生,有面试问题,就找面试哥。

    我创建了Interceptor,并使用Hibernate EmptyInterceptor对其进行了扩展。保存对象时将调用
    Override方法onSave(),该对象尚未保存到数据库中,而onFlushDirty()更新对象时将调用该方法,该对象尚未更新到数据库中。
    在此功能中,我已通过其名称检查方法,其中必须在创建或更新时设置日期。
    这是onFlushDirty()方法的示例代码。

    public boolean onFlushDirty(Object entity,Serializable id,Object[] currentState, 
                      Object[] previousState,String[] propertyNames, Type[] types) 
    {
    
        if ( entity instanceof City ) {
    
            for ( int i=0; i < propertyNames.length; i++ ) {
                if ( "lastUpdatedOn".equals( propertyNames[i] ) ) {
                    currentState[i] = new Date();
                    return true;
                }
            }
        }
        return false;
    }
    

    lastUpdatedOn是我的方法名称,它设置了更新的记录日期。

    onSave()方法:

    public boolean onSave(Object entity, Serializable id, Object[] state,   
                         String[] propertyNames, Type[] types)   
    {
        if ( entity instanceof City) {
    
            for ( int i=0; i<propertyNames.length; i++ ) {
                if ( "createdOn".equals( propertyNames[i] ) ) {
                    state[i] = new Date();
                    return true;
                }
            }
        }
        return false;
    }
    

    createdOn是设置记录创建日期的方法。

    使用此拦截器类扩展您的POJO类。



推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看