当前位置: 首页 > 知识库问答 >
问题:

在PersistenceException catch子句中执行JPQL查询会再次引发PersistenceException

臧正平
2023-03-14

我正在尝试使用JPA在我的JavaEE应用程序中的DAO中实现一些错误处理。

我遇到的情况是,有人(用户)可能会尝试将重复项输入到我的数据库中。我的计划是尝试持久化我的实体,例如user(“”)test@test.com,“Test”,“password”)。如果由于PersistenceException而失败,我想我可以在用户名(“Test”)和电子邮件(“email”)等唯一列上检查重复条目test@test.com). 如果我发现一个重复,我想检查它失败的列,并相应地通知用户。

我的尝试如下:

getEntityManager().persist(entity);
try {
    getEntityManager().flush();
} catch (PersistenceException ex) {
    List<T> duplicates = findDuplicate(entity);
    if (duplicates.size() > 0) {
        // Notify user
    } else {
        // Probably pass exception forwards
    }
}

实体管理器被注入到类中:

@PersistenceContext(unitName = "RecruitmentPU")
protected EntityManager mEM;

getEntityManager()只是返回这个成员。它本身的类被注释为@Statless。

要找到一个副本,我基本上只是这样做:

String column = myEntity.getUniqueColumn(); // returns the name of the column
Object uniqueValue = myEntity.getUniqueValue(); // returns the value of the unique column

Query query = getEntityManager().createQuery(
        "SELECT e FROM TestEntity e WHERE " + column + " = :identifier",
        TestEntity.class
);

query.setParameter("identifier", uniqueValue);
List<T> entries = null;
try {
    entries = (List<T>) query.getResultList(); // Here the exception is re-thrown
} catch(Exception ex) {
    System.out.println("Caught something... \n" + ex.getMessage());
}

该实体还有一个ID列,注释为< code > @ generated value(strategy = generation type。身份)。还有一个< code>@ManyToOne属性在我简化代码时被删除了。当我测试它时,我得到以下输出:

Info:   Caught something... 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.3.qualifier): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'Test' for key 'username_UNIQUE'
Error Code: 1062
Call: INSERT INTO test.test (email, username, role) VALUES (?, ?, ?)
        bind => [3 parameters bound]
Query: InsertObjectQuery(ID: 0 | email: test@test.com | username: Test | password: ********)

目前我让容器处理事务,但是我有预感我会遇到这些问题,因为我试图在第一个事务完成之前查询数据库(或者类似的事情)。

是战略中的缺陷还是实施中的缺陷?我可以采取哪些步骤来开始解决这个问题?

共有1个答案

乐正辰阳
2023-03-14

发生异常后,您不想继续任何事务。

我建议你切换操作顺序,如下所示:

  1. 查询数据库中具有唯一密钥的记录,该唯一密钥等于要持久化的实体的唯一密钥。
  2. 坚持你的实体
 类似资料:
  • 问题内容: 在MySQL中执行子句的预定义顺序是什么?它是否在运行时确定,并且此顺序正确吗? 问题答案: MySQL语句的实际执行有些棘手。但是,该标准确实指定了查询中元素解释的顺序。这基本上是在您指定的顺序,但我想和能来后: 条款 条款 条款 条款 条款 条款 这对于了解如何解析查询很重要。例如,您不能使用在子句中的定义的列别名,因为会在之前解析。另一方面,这样的别名可以在子句中。 至于实际执行

  • 问题内容: 这是SQL中的JOIN问题更新语句的扩展,但是我试图使用Spring Data JPQL。 我正在尝试将更新与JPQL中的JOIN一起使用,如下所示 但是,我得到如下错误 org.hibernate.hql.internal.ast.QuerySyntaxException:期望“设置”,找到“ JOIN” JPQL中无法进行UPDATE和JOIN吗?有什么选择。谢谢 问题答案: 该J

  • 这是在SQL中使用JOIN的question Update语句的扩展,但我正在尝试使用Spring Data JPQL。 我试图在JPQL中使用Update和JOIN,如下所示 在JPQL中是否不能更新和连接?另一种选择是什么。谢谢

  • 我的ParkingLotEntity: 我的Jpa存储库接口 上面的两个方法运行良好,但问题是我还需要从结果集到第二个方法“GetAllParkingLotCurrentlyWorkingInRegionOfRadius”中的位置的任何停车场之间的距离!在SQL Server中,我的定义函数已经计算出了距离。方法2的结果集是成功的,但没有返回距离(这是我的需要),只是一组parkingLotEnt

  • 问题内容: 如何在Firebase Android中查询SQL IN子句?我想在Firebase Recycler适配器中使用它,以便根据某些条件仅检索某些子级。类似于以下语句: 我需要一个Firebase查询才能在Firebase Recycler适配器中使用它。 问题答案: 我找到了解决方案:我们无法使用。相反,我们必须创建可扩展的自定义适配器。 要将值传递给此适配器,首先我们必须使用检索数据

  • 所以myTable有一个列,我需要从中获取最大id并在查询中使用它。 最后一行给了我一个错误: 运行查询时出错:在EntityManager中创建查询时出现异常:< br > Java . lang . illegalargumentexception:在EntityManager中创建查询时出现异常:异常描述:语法错误解析[上面的查询]。[214,214]必须为范围变量声明提供标识变量。