首页 > 解决方案 > 检查表然后为 Hibernate 保存/更新的正确做法

问题描述

所有使用休眠的应用程序都需要保存和更新才能与数据库交互。为了保存,我将检查一些标准的存在。如果它不存在,我会保存。对于更新,我会检查存在和某些标准来确定是否更新。进行检查和保存/更新的最佳做法是什么?

我目前正在创建一个单独的函数来打开一个会话并搜索以确定存在。会话打开/关闭非常笨拙。我认为应该有更好的方法来做到这一点。

public Event searchByDateAddress(Date _date, String _address, boolean _closeSess)
{
    try
    {
        if(!session.isOpen())
        {
            session = HibernateUtil.getSessionFactory().openSession();
        }
        session.beginTransaction();
        Criteria criteria = session.createCriteria(Event.class);
        criteria.add(Restrictions.eq("date", _date));
        criteria.add(Restrictions.eq("address", _address));
        criteria.setFetchMode("organizerProfile", FetchMode.JOIN);
        Event evt = (Event)criteria.uniqueResult();
        if(_closeSess)
        {
            session.close();
        }
        if (evt==null)
        {
            LogUtils.logInfo("The event does not exist: " + _date + " " + _address);
            return null;
        }
        else
        {
            return evt;
        }
    }
    catch(Exception e)
    {
        LogUtils.logInfo(e.toString());
        if(_closeSess)
        {
            session.close();
        }
        return null;
    }
}


public EventDTO insertEvent(Event _event)
{
    try
    {
        Event tmpEvent=new Event();
        //Event not exists
        if((tmpEvent=this.searchByDateAddress(_event.getDate(), _event.getAddress(), true))==null)
        {
            //insert
            if(!session.isOpen())
            {
                session = HibernateUtil.getSessionFactory().openSession();
            }
            Transaction tx=session.beginTransaction();
            long retOid=(Long)session.save(_event);
            session.flush();
            tx.commit();
            session.close();
            _event.setOid(retOid);
            return new EventDTO(_event);
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
        session.close();
    }
    return new EventDTO();
}

谢谢

标签: javahibernate

解决方案


关于会话处理,最好在 API 级别处理,在这个“EventService”之前的一个级别。所以你总是假设会话在服务方法中是可用的。然后代码看起来更简洁,避免与休眠查询会话。

@Transactional也可以在需要会话的方法中使用属性来完全避免会话处理。使用 Spring 可以做到这一点。查看:https ://spring.io/guides/gs/managing-transactions/了解更多信息。

为了检查一个表是否有你的 where 子句的数据,你可以使用 count(*)。因此,您不需要首先获取所有数据。

看这个例子:hibernate native query, count


推荐阅读