Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用多个@Transactional注释方法?_Java_Spring_Hibernate_Jpa_Spring Transactions - Fatal编程技术网

Java 如何使用多个@Transactional注释方法?

Java 如何使用多个@Transactional注释方法?,java,spring,hibernate,jpa,spring-transactions,Java,Spring,Hibernate,Jpa,Spring Transactions,我有一个springboot项目,其中有一个带有2个@Transactional注释方法的服务bean 这些方法使用JPA存储库和实体中的惰性加载getter,执行只读JPA(休眠)操作以从HSQL文件数据库获取数据 我还有一个处理命令的clibean(使用PicoCLI)。通过其中一个命令,我尝试调用两个@Transactional带注释的方法,但在执行第二个方法时,我得到以下错误: org.hibernate.LazyInitializationException - could not i

我有一个springboot项目,其中有一个带有2个
@Transactional
注释方法的服务bean

这些方法使用JPA存储库和实体中的惰性加载getter,执行只读JPA(休眠)操作以从HSQL文件数据库获取数据

我还有一个处理命令的clibean(使用PicoCLI)。通过其中一个命令,我尝试调用两个
@Transactional
带注释的方法,但在执行第二个方法时,我得到以下错误:

org.hibernate.LazyInitializationException - could not initialize proxy - no Session
        at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:602)
        at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:217)
        at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:581)
        at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:148)
        at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:188)
        at java.util.Spliterators$IteratorSpliterator.estimateSize(Spliterators.java:1821)
        at java.util.Spliterator.getExactSizeIfKnown(Spliterator.java:408)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566)
        at <mypackage>.SomeImpl.getThings(SomeImpl.java:<linenr>)
...

实施:

public类SomeImpl实现SomeApi{
@交易的
公共列表getSomeList(){
return…;//执行jpa操作以获取列表
}
@交易的
公共列表getThings(字符串somethingGroupName){
return…;//执行其他jpa操作以从组名获取结果
}
}
第三方使用(可能不知道什么是交易性):

public somethod(String something groupname){
...
SomeApi SomeApi=…;//以某种方式获取api的实现
List-someList=someApi.someList();
if(someList.contains)(somethingGroupName){
System.out.println(someApi.getThings(somethingGroupName));
}
...
}

在事务结束后,您似乎正在从实体访问一些未初始化的数据。在这种情况下,持久性提供程序可能会抛出lazyinitialization异常

如果需要检索一些不急于加载实体的信息,可以使用以下两种策略之一:

  • 也使用@Transactional annotation注释调用方法,就像您所做的那样:它不会为每个调用启动新事务,而是使打开的事务处于活动状态,直到调用方法结束,从而避免异常;或者
  • 使用joinfetchjpql习惯用法,让被调用的方法急切地加载所需的字段

事务边界需要对您的场景进行一些分析。请阅读并搜索更好的书籍或教程来掌握它。可能只有您才能恰当地定义您的需求。

在事务结束后,您似乎正在从实体访问一些未初始化的数据。在这种情况下,persistence提供程序可能引发lazyinitialization异常

如果需要检索一些不急于加载实体的信息,可以使用以下两种策略之一:

  • 也使用@Transactional annotation注释调用方法,就像您所做的那样:它不会为每个调用启动新事务,而是使打开的事务处于活动状态,直到调用方法结束,从而避免异常;或者
  • 使用joinfetchjpql习惯用法,让被调用的方法急切地加载所需的字段

事务边界需要对您的场景进行一些分析。请阅读并搜索更好的书籍或教程来掌握它。可能只有您才能恰当地定义您的需求。

我发现hibernate开箱即用不会重新打开会话,因此在第一个事务结束后不会启用延迟加载d、 后续jpa语句是否在事务中。但是,hibernate中有一个属性可启用此功能:

spring:
  jpa:
    properties:
      hibernate.enable_lazy_load_no_trans: true
这将确保如果没有会话,那么将创建临时会话。我相信这也将防止会话在事务结束后结束,但我不确定这一点

以下是其他问题的答案,部分归功于此:


警告:在hibernate 4.1.8中存在一个可能导致数据丢失的错误!请确保您使用的是hibernate的4.2.12、4.3.5或更新版本。请参阅:。

我发现hibernate开箱即用不会重新打开会话,因此在第一个事务结束后不会启用延迟加载,无论是否使用UPENT jpa语句是否在事务中。但是,hibernate中有一个属性可启用此功能:

spring:
  jpa:
    properties:
      hibernate.enable_lazy_load_no_trans: true
这将确保如果没有会话,那么将创建临时会话。我相信这也将防止会话在事务结束后结束,但我不确定这一点

以下是其他问题的答案,部分归功于此:


警告:在hibernate 4.1.8中,存在一个可能导致数据丢失的错误!请确保您使用的是hibernate的4.2.12、4.3.5或更新版本。请参阅:。

从上面的描述中选择使用嵌套转换?@MykhailoMoskura我在上面描述了我现在正在这样做。我想知道的是这是否是ri还有一条路要走,或者如果有一种方法可以为不公开实体的事务性方法启动新会话,那么它们不应该相互干扰。@MykhailoMoskura同样,我不想让是否使其方法具有事务性的负担落在这些方法的用户身上。我希望他们能够按原样使用它们,这样就可以了如果希望使用多个事务性注释方法(这些方法将通过API库提供,因此将涉及第三方),则不希望将调用方法标记为事务性方法由于您的编辑,我问,在您的代码中,谎言发生在哪里?在someMethod中?您返回的列表是否为托管列表(Hibernate列表的一些实现)还是在API中构建的列表?@PauloAraújo getSomeList实际上不返回字符串,而是包含所述字符串+另一个字符串列表的POJO,例如,我对其进行了简化。它调用某个存储库上的findAll以获取某个实体的iterable。然后我使用该iterable的拆分器和
streamsupper创建了一个流t
。我使用自行实现的apache将实体映射到特定POJO的流