Hibernate - 交易的样板代码
Posted
技术标签:
【中文标题】Hibernate - 交易的样板代码【英文标题】:Hibernate - Boilerplate code for transactions 【发布时间】:2013-01-12 01:36:23 【问题描述】:我已经为数据库 CRUD 操作编写了这个服务类。
可见的公共类 CompanyServiceImpl 扩展 PersistentRemoteService 实现 CompanyService
private GileadHibernateUtil gileadHibernateUtil;
public CompanyServiceImpl()
gileadHibernateUtil = new GileadHibernateUtil();
setBeanManager(gileadHibernateUtil.getPersistentBeanManager());
@Override
public void addCompany(Company newCompany)
Objects.requireNonNull(newCompany, "newCompany is null.");
Session session = gileadHibernateUtil.getCurrentSession();
Transaction transaction = null;
try
transaction = session.beginTransaction();
session.persist(newCompany);
session.getTransaction().commit();
finally
if (transaction.isActive())
transaction.rollback();
session.close();
@Override
public Company updateCompany(Company company)
Objects.requireNonNull(company, "company is null.");
Session session = gileadHibernateUtil.getCurrentSession();
Transaction transaction = null;
Company managedCompany = null;
try
transaction = session.beginTransaction();
managedCompany = (Company) session.merge(company);
session.getTransaction().commit();
finally
if (transaction.isActive())
transaction.rollback();
return managedCompany;
@Override
public void deleteCompany(Company company)
Objects.requireNonNull(company, "company is null.");
Session session = gileadHibernateUtil.getCurrentSession();
Transaction transaction = null;
try
transaction = session.beginTransaction();
session.delete(company);
session.getTransaction().commit();
finally
if (transaction.isActive())
transaction.rollback();
@Override
public Company findCompany(int companyId)
if (companyId <= 0)
throw new IllegalArgumentException("companyId must be a positive integer.");
Session session = gileadHibernateUtil.getCurrentSession();
Transaction transaction = null;
Company company = null;
try
transaction = session.beginTransaction();
company = (Company) session.get(Company.class, companyId);
session.getTransaction().commit();
finally
if (transaction.isActive())
transaction.rollback();
return company;
@Override
public List<Company> findMatchingCompanies(String companyName)
Session session = gileadHibernateUtil.getCurrentSession();
Transaction transaction = null;
List<Company> matchingCompanies = null;
try
transaction = session.beginTransaction();
Criteria searchCriteria = session.createCriteria(Company.class).add(
Restrictions.or(Restrictions.like("code", companyName), Restrictions.like("name", companyName)));
session.getTransaction().commit();
matchingCompanies = searchCriteria.list();
finally
if (transaction.isActive())
transaction.rollback();
return matchingCompanies;
@Override
public List<Company> findAllCompanies()
Session session = gileadHibernateUtil.getCurrentSession();
Transaction transaction = null;
List<Company> companies = null;
try
transaction = session.beginTransaction();
Criteria searchCriteria = session.createCriteria(Company.class);
session.getTransaction().commit();
companies = searchCriteria.list();
finally
if (transaction.isActive())
transaction.rollback();
return companies;
我决定不使用单独的 DAO 层。它是一个小应用程序,我不会从 Hibernate 切换。它所包含的只是 Hibernate 会话命令。开始和结束事务仍然来自业务层。所以,Hibernate 几乎可以作为我的 DAO 层。 困扰我的是看似样板的交易代码,必须在每个 CRUD 方法中编写。 这是更好的方法,还是无论如何都要重复的最少代码量?
【问题讨论】:
你考虑过使用 Spring 的 Hibernate 支持框架吗? @ToddMurray 目前,它不是一个选项。这是主要问题。 【参考方案1】:如果您使用的是 spring 并且能够使用注解。提供的链接上有一篇很好的文章,它展示了如何使用注释来包装事务中的方法。
http://springinpractice.com/2008/03/18/annotation-based-transactions-in-spring/
同时使用 spring 和 hibernate 将使您的代码看起来更干净,并且看起来像下面的内容。
@Override
@Transactional
public void addCompany(Company newCompany)
Objects.requireNonNull(newCompany, "newCompany is null.");
Session session = gileadHibernateUtil.getCurrentSession();
session.persist(newCompany);
//session.close(); this line would also not be needed because the session would close automatically when the transaction is complete.
【讨论】:
是的。我在几个地方读到 Spring 将帮助清理代码。但是,我现在不应该使用 Spring。那我有什么选择呢? 不确定声明式事务还有哪些其他替代方案。您可能想尝试某种 aop 解决方案。但这也需要另一个库,您可能无法像 AspectJ 那样使用它。 好的。我想我会等一天才能接受这个正确答案。【参考方案2】:没有弹簧,这样的事情可以使用
java.util.function.Function
public static Object transactionExecutor(Function<Session, Object> toRun)
Session session = null;
Object result = null;
try
session = getSession();
final Transaction tx = session.beginTransaction();
result = toRun.apply(session);
session.flush();
tx.commit();
return result;
catch (HibernateException he)
Transaction tx = session.getTransaction();
tx.rollback();
finally
session.close();
return result;
public static void save(final Students S)
Function<Session, Object> toRun = new Function<Session, Object>()
@Override
public Object apply(final Session t)
t.save(S);
return S.getId();
;
int saveID = (int)transactionExecutor(toRun);
【讨论】:
以上是关于Hibernate - 交易的样板代码的主要内容,如果未能解决你的问题,请参考以下文章
使用 Hibernate @SQLDelete 对所有实体进行软删除
“Spring 事务”和“Hibernate 事务”有啥区别