小编典典

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

hibernate

我已经使用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()方法,如代码所示。

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


阅读 443

收藏
2020-06-20

共1个答案

小编典典

我创建了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类。

2020-06-20