首页 > 解决方案 > JPA - JTA - 两个大问题(在 .persist() 和 .remove() 上) - MySQLIntegrityConstraintViolationException

问题描述

首先,如果我找不到任何关于我想描述的内容真正解决了我的问题,我想道歉。这并不意味着我在网站上进行了充分的搜索。虽然我已经花费了太多时间(天)。我也是新来的(从某种意义上说,我从未写过/回复过 SO 用户)。对于我可能出现的英语错误,我深表歉意。

我不得不说我是 Java EE 的新手。我正在使用 MySQL 开发 WildFly 14。我现在专注于 JPA 问题。我有一个唯一性约束。我正在做测试,在执行唯一性违规测试时,从数据源级别我得到一个 MySQLIntegrityConstraintViolationException,没关系。我有一个问题,persist() 方法不允许我捕获异常(我什至将 Throwable 放在子句中,但什么都没有......)。我强烈、严格地需要抓住这一点,以便在我的工作代码中管理一个关键过程(即间接包含对 .remove() 的调用)。

顺便说一句,尝试编写该异常时,系统不会向我显示建议的类/注释/等的窗口,建议我只创建类“MySQLIntegrityConstraintViolationException”。使用 MySQL 在 WildFly 上工作是否足以获得建议?

没有找到解决方案,我决定改变:我决定使用.createNativeQuery(),而不是使用persist(),在其中我将描述数据库中插入的字符串作为参数。它似乎工作。确实它有效(信号唯一性违规(ok!),不执行 TRY 块代码(ok!)并进入 CATCH 块(ok!))。但是,同样,异常/错误并不清楚。此外,当我在代码中输入负责管理捕获然后执行内部内容的代码时(并且我有一个 .remove(),内部),它会引发异常:

“执行此操作需要事务(使用事务或扩展持久性上下文)”-> 这指的是我的 entityManager.remove() 执行..

现在我无法理解.. JPA/JTA 不应该自动管理交易吗?

此外,稍后尝试放置 entityManager.getTransaction().begin() (和 commit()),这给了我一个问题,即尝试手动管理事务,而我却不能......似乎是一个无休止的循环......

[编辑]:我在 CMT 环境中工作,所以我只能使用 EntityManager 和 EntityManagerFactory。我尝试过 entityManager.getTransaction().begin() 和 entityManager.getTransaction().commit() ,但没有成功。

[编辑']:.getTransaction(EntityTransaction 对象)不能在 CMT 上下文中使用,因此它不起作用。

[edit'']:我已经通过适合 CMT 上下文的事务管理解决了事务问题:JTA + CMT 要求我们使用 TRY-CATCH-FINALLY 块来管理事务,在其 TRY 主体中需要它将我们想要在数据库上执行的操作以及需要将 EntityManager 对象关闭 (em.close()) 放在其最终主体中。虽然,如上所述,我使用了 em.createNativeQuery(),但在失败时会引发可捕获(在我的应用程序中可捕获)异常;我真的需要在我的工作代码中进行回滚(.createNativeQuery() 的使用是临时的)并使用 .persist() 方法,所以我需要知道该怎么做才能捕捉到 MySQLIntegrityConstraintViolationException .

非常感谢!

标签: jpatransactionsjtajava-ee-8

解决方案


看来我已经解决了这个问题。

回滚到使用 .persist() (因此,丢弃 createNativeQuery()),将 em.flush() 放在 em.persist(my_entity_object) 之后对我有帮助,因为一旦违反了唯一性约束(见上文) ,引发的异常现在可以捕获。有了可捕获的异常,我现在可以按照文章开头所述进行操作。

警告:我提醒您我是 JavaEE-JPA-JTA 的新手。我一直很“幸运”,因为由于我缺乏知识,我通过猜测(我不知道我怎么能想到)来输入该指令(em.flush())。因此,我无法解释这种行为;不过,我会很感激任何解释可能发生的事情,如何以及何时使用方法 flush() 等等。

谢谢!


推荐阅读