Java 事务重用的Hibernate模式

Java 事务重用的Hibernate模式,java,hibernate,session,transactions,Java,Hibernate,Session,Transactions,我编写了一个基本方法,以避免反复重复相同的hibernate会话/事务逻辑。这相当简单,但有一个具体的问题,我不确定是否可以用这种方法解决 假设您有一个用户实体和一个权限实体。如果请求保存一个用户及其匹配的权限,那么我认为在一个事务中执行这两个操作是有意义的,因为只能保存其中一个实体可能会被视为数据损坏。例如,如果未能保存用户的权限,则需要回滚以前插入的用户数据 我使用了以下方法来允许通用的hibernate操作,如果有必要的话,这些操作可以与当前事务一起工作,尽管我现在认为在当前形式下,它在调

我编写了一个基本方法,以避免反复重复相同的hibernate会话/事务逻辑。这相当简单,但有一个具体的问题,我不确定是否可以用这种方法解决

假设您有一个用户实体和一个权限实体。如果请求保存一个用户及其匹配的权限,那么我认为在一个事务中执行这两个操作是有意义的,因为只能保存其中一个实体可能会被视为数据损坏。例如,如果未能保存用户的权限,则需要回滚以前插入的用户数据

我使用了以下方法来允许通用的hibernate操作,如果有必要的话,这些操作可以与当前事务一起工作,尽管我现在认为在当前形式下,它在调用session.beginTransaction后将无法工作;即使以前的交易尚未提交,也可能会返回新的交易。是这样吗?。假设我更改了它以使其返回当前会话和事务,如果指定当前事务将有更多操作,您认为它会工作吗?这样做是明智的,还是你会建议改变方法?谢谢

protected <T> void baseOperation(Class<T> entityClass, List<T> instances, BaseHibernateDAO.Operations operation, boolean isLastOperation) throws Exception
{
    Session session = null;
    Transaction transaction = null;
    boolean caughtException = false;

    //get session from factory
    session = HibernateSessionFactory.getSession();

    try
    {
        //get current transaction
        transaction = session.beginTransaction();

        for (Object instance : instances) //perform operation on all instances
        {
            log.debug(String.format("Will perform %s operation on %s instance.", operation.name(), entityClass.getName()));

            switch (operation) //perform requested operation
            {
                case SAVE:
                    session.save(instance);
                    break;
                case UPDATE:
                    session.update(instance);
                    break;
                case SAVEORUPDATE:
                    session.saveOrUpdate(instance);
                    break;
                case DELETE:
                    session.saveOrUpdate(instance);
                    break;
            }

            log.debug(String.format("%s operation on %s instance was succesful.", operation.name(), entityClass.getName()));
        }

        session.flush(); //synchronize

        if (isLastOperation) //if this is the last operation of the transaction
        {
            transaction.commit();
            log.debug("Transaction commited succesfully.");
        }
    }
    catch (Exception e) //error occurred
    {
        caughtException = true;

        //roll-back if transaction exists
        if (transaction != null)
        {
            transaction.rollback();
        }

        //log and re-throw
        log.error("An error occurred during transaction operation.", e);
        throw e;
    }
    finally //cleanup tasks
    {
        if (isLastOperation || caughtException) //close session if there are no more pending operations or if an error occurred
        {
            HibernateSessionFactory.closeSession();
        }
    }
}

明智的做法是停止尝试重写已经编写、调试、拖泥带水、调试更多、部署数千次的代码。也就是说,您遇到的问题和考虑事项以前已经遇到并克服过,并且解决方案已经得到验证。此外,它们已经被广泛使用和改进,使用起来比您在自定义解决方案中投入的精力要少得多。退房,尤其是和。为了进一步阅读,这里有一个整体

我有一个示例,您可以看到一个非常简单的示例,使用Spring在使用Spring MVC的webapp上下文中管理Hibernate会话和事务

更新:对于那些后来出现的人,这样他们就不必仔细阅读评论:


使用Spring事务处理有三种通用方法:声明式、声明式或编程式

明智的做法是停止尝试重写已经编写、调试、拖泥带水、调试更多、部署数千次的代码。也就是说,您遇到的问题和考虑事项以前已经遇到并克服过,并且解决方案已经得到验证。此外,它们已经被广泛使用和改进,使用起来比您在自定义解决方案中投入的精力要少得多。退房,尤其是和。为了进一步阅读,这里有一个整体

我有一个示例,您可以看到一个非常简单的示例,使用Spring在使用Spring MVC的webapp上下文中管理Hibernate会话和事务

更新:对于那些后来出现的人,这样他们就不必仔细阅读评论:


使用Spring事务处理有三种通用方法:声明式、声明式或编程式

说得好。另外,别忘了EJB3和基于JSR-299的Seam 3的其他基于标准的选项。这并不是说我愿意重写它,我只是不知道它的存在。问题是我目前没有时间学习另一个框架。我看了你的例子,它看起来很简单,但我知道,一旦我尝试将它应用到更复杂的对象,情况就不会是这样了。我还没有找到一个在一个事务中运行两个操作的示例,在spring或其他时候,我发现最多的是三个点。。。这意味着会有更多的代码。如果我看不到它,我就无法理解它,因此我宁愿自己去做,即使它没有被尝试和验证。但是无论如何,感谢你为我指明了方向,我会在有时间的时候试着学习Spring,但是现在在开发时学习这样的东西太冒险了:实际上就是这么简单。您没有看到在一个事务中执行两个操作的任何示例的原因是,一个、两个或多个事务的差异完全为零。声明性事务的全部要点是它们包含1..n个持久性操作。对于事务和资源管理这样复杂的事情,不使用既定的解决方案通常是风险较高的途径。如果你坚持自己做,我能提供的最好建议是浏览Spring源代码中的TransactionTemplate,然后HibernateTemplate类来完成你想做的事情。谢谢你的帮助,我会检查一下。但是我想了解一些事情。。。在spring中,如何定义应该在单个事务中运行哪些操作?我设想,可能每个BL方法都设置为在单个事务中运行。如果是这种情况,如何通过注释等来实现?我确实读了一些文档和样本,但我没能理解它是如何工作的。这一点很好。也不要
忘了EJB3和基于JSR-299的Seam 3的其他基于标准的选项吧。这并不是说我愿意重写它,我只是不知道它的存在。问题是我目前没有时间学习另一个框架。我看了你的例子,它看起来很简单,但我知道,一旦我尝试将它应用到更复杂的对象,情况就不会是这样了。我还没有找到一个在一个事务中运行两个操作的示例,在spring或其他时候,我发现最多的是三个点。。。这意味着会有更多的代码。如果我看不到它,我就无法理解它,因此我宁愿自己去做,即使它没有被尝试和验证。但是无论如何,感谢你为我指明了方向,我会在有时间的时候试着学习Spring,但是现在在开发时学习这样的东西太冒险了:实际上就是这么简单。您没有看到在一个事务中执行两个操作的任何示例的原因是,一个、两个或多个事务的差异完全为零。声明性事务的全部要点是它们包含1..n个持久性操作。对于事务和资源管理这样复杂的事情,不使用既定的解决方案通常是风险较高的途径。如果你坚持自己做,我能提供的最好建议是浏览Spring源代码中的TransactionTemplate,然后HibernateTemplate类来完成你想做的事情。谢谢你的帮助,我会检查一下。但是我想了解一些事情。。。在spring中,如何定义应该在单个事务中运行哪些操作?我设想,可能每个BL方法都设置为在单个事务中运行。如果是这种情况,如何通过注释等来实现?我确实读了一些文件和样本,但我没能理解它是如何工作的。