Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA异常处理(唯一约束,名称太长)sql层与java层?_Java_Exception_Jpa_Exception Handling_Unique Constraint - Fatal编程技术网

JPA异常处理(唯一约束,名称太长)sql层与java层?

JPA异常处理(唯一约束,名称太长)sql层与java层?,java,exception,jpa,exception-handling,unique-constraint,Java,Exception,Jpa,Exception Handling,Unique Constraint,我想知道大多数应用程序是如何强制执行唯一ID的(例如,任何网站注册的用户名) 我的服务器端实现的一种方法是: 每次我得到一个新的ID时都要查询数据库。这个查询是用带有JPA的Java代码组成的。例如: //compose query myQuery.where(...); myQuery.from(...); ... TypedQuery<> search= entityManager.createQuery(myQuery); //get result search.getResu

我想知道大多数应用程序是如何强制执行唯一ID的(例如,任何网站注册的用户名)

我的服务器端实现的一种方法是:

每次我得到一个新的ID时都要查询数据库。这个查询是用带有JPA的Java代码组成的。例如:

//compose query
myQuery.where(...);
myQuery.from(...);
...
TypedQuery<> search= entityManager.createQuery(myQuery);
//get result
search.getResultList();
//组合查询
myQuery.where(…);
myQuery.from(…);
...
TypedQuery search=entityManager.createQuery(myQuery);
//得到结果
search.getResultList();
这对我来说太贵了。这是有问题的

a) 我不确定何时/如何优化此查询。因为我可能在数据库列上没有优化此特定查询的索引类型

b) 当JPA将我的实体持久化到数据库时,db将再次检查唯一约束(如果我在列中添加了一个约束)。因此,相同的唯一检查发生了两次

c) 多线程,线程A从db获取所有ID并开始比较唯一性。在此期间,线程B将保持id。当A完成比较并保持id时,它将再次命中db unique约束。这使得这张支票毫无用处

所以,我希望只使用数据库层的唯一性检查,我相信它有更多的优化能力。但问题来了:

  • 只有在执行
    entityManager.commitTransaction()
    时,唯一约束才会引发
    RollbackException
    。捕获回滚异常并提取实际原因(
    ORA-00001:unique constraint(constraint_name)违犯了
    )并将其呈现给最终用户是非常困难的。 我该怎么做
  • 对于
    ORA-12899,同样的问题是:列的值太大。出于同样的原因,我不想检查java代码的长度。所以我希望,如果将来我更新我的db列长度,它会自动向最终用户反映这一点
    
    您可以围绕服务方法编写自定义方面/拦截器,以拦截所有调用和返回的结果,包括抛出的异常。然后,您可以对异常做出反应,并创建适当的错误消息

    在您的情况下,更简单的解决方案是显式刷新持久性上下文,并立即捕获此类数据库约束冲突:

    User user = ...
    user.setUsername(username);
    ...
    entityManager.persist(user)
    try {
      entityManager.flush(); // Force synchronization with database
    } catch (SomeException e) {
      if (<cause of the exception is database constraint violation>) {
        throw new ValidationException("Username already exists.");
      } else {
        throw e;
      }
    }
    
    User=。。。
    user.setUsername(用户名);
    ...
    entityManager.persist(用户)
    试一试{
    entityManager.flush();//强制与数据库同步
    }捕获(某些例外){
    如果(){
    抛出新的ValidationException(“用户名已存在”);
    }否则{
    投掷e;
    }
    }
    
    相关链接: