java - 当我想使用find()方法两次时,我可以使用flush()而不是commit()吗?

标签 java hibernate jpa

我想知道用户名是否已在使用中,如果不是,则电子邮件地址是否已在使用中。我不想为每个实体管理器查找方法开始并提交一个新事务,因为我认为仅使用一个事务进行多个操作比使用多个操作更有效。我可以在我的方法中用flush()替换commit()吗?

    public void createUser(User_ newUser){
            UserDao userDao = new UserDao();
    Alert alert;
    EntityTransaction transaction = entityManager.getTransaction();

        try{
            transaction.begin();
            userDao.find("userName",newUser.getUserName());
            transaction.commit();
            alert = new Alert(Alert.AlertType.ERROR,"Username already in use", ButtonType.OK);
            alert.showAndWait();
            if (alert.getResult() == ButtonType.OK)alert.close();
        }        
        catch(NoResultException e){
            try{
                transaction.begin();
                userDao.find("emailAdress",newUser.getEmailAdress());
                transaction.commit();
                alert = new Alert(Alert.AlertType.ERROR,"E-mail adress already in use", ButtonType.OK);
                alert.showAndWait();
                if (alert.getResult() == ButtonType.OK) alert.close();             
                }
            catch(NoResultException x){
                    transaction.begin();
                    userDao.save(newUser);
                    transaction.commit();
                }
        }
        catch(RuntimeException e){
            transaction.rollback();    
        }
        finally{entityManager.close();}
} 

谢谢。

最佳答案

您的代码存在三个问题:

  1. 为什么要将查询方法包装在单独的事务中?首先,执行查询不需要查询。其次,您尝试将两个查询方法包装在一个事务中是正确的,但原因是错误的。这与性能关系不大,而与隔离密切相关。这里需要一个事务,只是为了防止在这两个查询之间再次调用 createUser 创建具有相同用户名的用户(显然,出于同样的原因,持久化用户应该是同一事务的一部分) )。

  2. 您应该避免使用异常来处理应用程序的正常状态。这不仅是使用异常的正确方法,而且就事务状态而言,您遇到的问题也会少得多。从您期望 userDao.find 抛出 NoResultException 的事实来看,我假设它在内部使用 query.getSingleResult() 。仅当您希望查询始终有结果时才应使用 getSingleResult。您应该使用 getResultList() 来代替,并结合空性检查,或者更好的是,查询具有给定用户名的 User 实体的 count

  3. 您的方法混合了业务逻辑和表示问题。将数据保存到数据库并显示警报绝对不应该通过单一方法完成。如果您绝对需要以与保存数据相同的方法向用户传达错误,请确保在提交事务之后执行此操作,以防止超时。

关于java - 当我想使用find()方法两次时,我可以使用flush()而不是commit()吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44088452/

相关文章:

java - 使用 PropertySourcesPlaceholderConfigurer 时如何解密属性值

java - 使用 EntityManager 更新 Hibernate

java - Hibernate - 在同一事务中使用 getNamedQuery 保存和插入

hibernate - JPA Hibernate 一对多批量插入

java - Spring Multi-Tenancy Web 服务 : postgres vs mongodb

java - 如何在 Solr 中设置查询排序规则

java - 两个接口(interface)中的弃用方法

java - 在 Maven 中指定源和测试文件夹的 IntelliJ 包前缀

java - org.hibernate.LazyInitializationException 关联集合

java - 如何在 Hibernate 上从 JPA 手动调用 create-drop?