我如何通过获取一些不受对象管理器管理的值来避免 NucleusUserException

How I can avoid NucleusUserException by obtaining some value not managed by an Object Manager

我有需要的业务逻辑

1) 做一些类似count或'find id of top 1 item with field greater than a'的动作,即对entity A做一些读取动作。count或find涉及超过25个item,所以它会影响到很多Entity groups。 2) 然后对另一个实体 B 执行一些操作并持久化更改后的实体 3) 现在我更改了实体 A 的唯一对象并希望保留它

如果我不在我的方法上使用 Spring @Transactional,我会得到 ID 为 "A@someHash" 的对象在调用 3) 时由不同的对象管理器管理。根据 System.out.println(NucleusJPAHelper.getObjectState(busRouteToCheck));对象处于持久状态

如果我使用 Spring @Transactional 覆盖整个方法,我得到 "too many Entity groups opened in the single transaction"

我如何强制 1) 的结果不由对象管理器管理,最终获得一些 Long 值和过程 3) 就像我在我的方法中第一次处理 A 一样。最后,我需要读取多个实体组的项目,并且在事务中只更新两个。

我尝试解决的问题:1) 将整个方法分成 3 个,其中 2 个没有 @Transaction,1 和 3 有 @Transaction;在这里我仍然得到 NucleusUserException; 2) 在相同的条件下,我尝试使用 2 个不同的事务管理器,首先调用只读调用(方法 1),然后用第二个(方法 3)写入。

是否有明确的方法来管理对象管理器?

使用的依赖项是:

   <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-api-jdo</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-api-jpa</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.appengine.orm</groupId>
            <artifactId>datanucleus-appengine</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-core</artifactId>
            <version>3.1.1</version>
        </dependency>

增强器插件是

  <plugin>
                <groupId>org.datanucleus</groupId>
                <artifactId>maven-datanucleus-plugin</artifactId>
                <version>3.1.3</version>
                <configuration>
                    <!-- Make sure this path contains your persistent classes! -->
                    <!--<mappingIncludes>**/domain/*.class</mappingIncludes>-->
                    <!--<persistenceUnitName>transactions-optional</persistenceUnitName>-->
                    <verbose>true</verbose>
                    <api>JPA</api>
                    <!--<mappingIncludes>com/appspot/Player.class</mappingIncludes>-->
                    <!--<metadataIncludes>com/appspot/Player.class</metadataIncludes>-->
                    <fork>false</fork>
                </configuration>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <!--<dependency>
                        <groupId>asm</groupId>
                        <artifactId>asm-commons</artifactId>
                        <version>3.3.1</version>
                    </dependency>-->
                    <dependency>
                        <groupId>org.datanucleus</groupId>
                        <artifactId>datanucleus-api-jpa</artifactId>
                        <version>3.1.1</version>
                    </dependency>
                    <dependency>
                        <groupId>org.datanucleus</groupId>
                        <artifactId>datanucleus-core</artifactId>
                        <version>3.1.1</version>
                    </dependency>
                    <dependency>
                        <groupId>org.datanucleus</groupId>
                        <artifactId>datanucleus-enhancer</artifactId>
                        <version>3.1.1</version>
                    </dependency>
                </dependencies>
            </plugin>

我不能说我详细了解了 google 的 JPA 实现中发生的事情并获得了我发布的异常。相反,我已经解决了我所面临的全球性问题。如果处理异常,我相信你会面临同样的问题。我试图解决在不需要事务的情况下更改事务中的少量对象和读取可能对象的限制(因为事务更新不是由于上述异常而失败)。

问题在体系结构上得到解决:1) 您应该在服务层中创建单独的方法来读取实体或获取计数,而不是使它们成为事务性的 2) 在服务层中创建单独的方法来获取非事务性方法的结果作为参数并更新实体;使这些方法具有事务性 3) 在控制器层或在控制器下方但在服务上方的自定义层中分别调用这些方法!

我的错误是我认为 Spring 的 @Transactional 注释是有意义的,即使从另一个没有 @Transactionl 的方法调用带有 @Transactional 的方法也是如此。这是错误的:由于注释的方面性质,它们只有在从 class 对象外部调用方法时才有意义。因此,在我的示例中,整个调用都在唯一的事务中(实体异常太多)或在 none 事务中(因此获取具有 id ... 的对象由不同的对象管理器管理)。因此,将非事务行为和事务行为分离到不同的方法并从外部调用它们对我很有帮助。