在PersistenceException catch子句中执行JPQL查询会重新抛出PersistenceExcept



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

我遇到过这样的情况,有人(用户)可能会试图在我的数据库中输入重复项。我的计划是尝试持久化我的实体,例如user("test@test.com","Test","password")。如果此操作失败并出现PersistenceException,我想我可以检查唯一列上的重复条目,如用户名("Test")和电子邮件("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()只返回此成员。它自身的类被注释为@Stateless。

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

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列,该ID列被注释为@GeneratedValue(strategy = GenerationType.IDENTITY)。还有一个@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. 查询DB中具有与要持久化的实体的唯一密钥相等的唯一密钥的记录
  2. 坚持你的实体

最新更新