mysql - 尝试使用 EntityManager 创建 NativeQuery 时出现 IllegalStateException

标签 mysql jakarta-ee eclipselink

在尝试使用我的实体管理器创建 native 查询时,我遇到了这个恼人的异常。完整的错误信息是:

java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: com.model.OneToManyEntity2@61f3b3b.
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:313)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:723)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:441)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:874)
at org.eclipse.persistence.internal.jpa.QueryImpl.performPreQueryFlush(QueryImpl.java:967)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:207)
at org.eclipse.persistence.internal.jpa.QueryImpl.getSingleResult(QueryImpl.java:521)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:400)

实际触发错误的代码是:

    Query query;
    query = entityManager.createNativeQuery(
            "SELECT MAX(CAST(SUBSTRING_INDEX(RecordID,'-',-1) as Decimal)) FROM `QueriedEntityTable`");
    String recordID = (query.getSingleResult() == null ?
            null :
            query.getSingleResult()
                 .toString());

这是通过 doTransaction 部分中的 EntityTransaction 执行的。不过,让我明白这一点的部分是,这是在 doTransaction 方法中执行的第一个代码,在下面简化为:

updateOneToManyEntity1();
updateOneToManyEntity2();
entityManager.merge(parentEntity);

“OneToManyEntity1”有问题的实体甚至不是我试图在其上创建查询的表。在这一点之前我也没有做任何坚持或合并,所以我也不确定是什么导致它不同步。在执行这段代码之前唯一正在完成的数据库工作只是提取数据,而不是更改任何内容。外键已在数据库中正确设置。

我能够按照它所说的那样操作并将这些关系标记为 Cascade.PERSIST 来消除此错误,但随后我在 query.getSingleResult() 行上收到 MySQLContrainstraViolationException。我的日志显示它在此之前执行了一些 INSERT 查询,因此看起来它到达了我的 doTransaction 方法的 EntityManager.merge 部分,但错误和调用堆栈指向代码的完全不同的部分。

使用 EclipseLink (2.6.1)、Glassfish 4 和 MySQL。 entitymanager 正在使用 RESOURCE_LOCAL,所有必要的类都列在 persistence-unit 标签下,exclude-unlisted-classes 设置为 false。

编辑:在我尝试解决这个问题时提供更多信息。如果我在事务的开头放置一个断点,然后通过 IntelliJ 的“评估表达式”工具执行 entityManager.clear(),至少在第一次通过时一切正常。没有它,我会在尝试将空对象插入表中时收到错误消息。

编辑 #2:我将 nativeQuery 部分转换为使用 Criteria API,这让我实际上通过我的代码实现了它,因此我可以找到它无意中将空对象添加到我的实体列表的位置。我仍然对为什么实体管理器缓存这些错误或某些东西感到困惑,以至于创建 native 查询正在中断,因为它仍在尝试插入错误数据。这是我每次做之前都需要调用 EntityManager.clear() 的东西吗?还是应该在 doTransaction 方法出错时调用它?

最佳答案

因此,在重新编写代码并将其搁置一旁之后,我偶然发现了至少部分问题的答案。我的问题是由对象在事务开始之前被持久化引起的。因此,当我进入我的事务时,它首先尝试从我的实体对象插入/更新数据并抛出错误,因为我没有设置大多数非空列的值。我相信这就是我收到级联错误的原因,而且我确信这是我在交易开始时看到的随机插入查询的来源。希望这可以帮助其他人避免很多麻烦。

关于mysql - 尝试使用 EntityManager 创建 NativeQuery 时出现 IllegalStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38923321/

相关文章:

java - 在构建 JSTL 经典 Select 标签后,我应该将 null 设置为大项吗

java - persistence.xml 缓存属性警告

eclipselink - 使用 JPA 在 Apache Derby 中创建表时出现 SQLSyntaxErrorException

maven - eclipselink maven 存储库不工作

php - MySQL - 选择不同

java - JPQL 新对象实例化

php - mySQL concat if null 删除文字

java - Apache netbeans IDE 10.0 安装了 JEE 支持,但注释仍然错误

php - 在 MySQL 服务器之间移植存储过程

mysql - 简单的SQL查询问题