- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到一个问题,如果我有一个客户端在我的服务上调用两个方法,则会失败,第二个方法中的事务没有与之关联的 session 。但是,如果我将这两种方法组合到服务中并从客户端代码调用该方法,那么它就会成功。
谁能向我解释一下为什么会发生这种情况?
考虑以下代码:
@Configurable
public class ParentService {
@PersistenceContext
private EntityManager entityManager;
public ParentService() {
}
@Transactional
public Parent findById( Long id ) {
return entityManager.findById( Parent.class, id );
}
@Transactional
public Set<Child> getChildrenFor( Parent parent ) {
return Collections.unmodifiableSet( new HashSet<>( parent.getChildren() ) );
}
@Transactional
public Set<Child> getChildrenFor( Long id ) {
Parent parent = findById( id );
return getChildrenFor( parent );
}
...
}
所以这里发生的情况是,在我的客户端代码(不了解事务)中,如果我调用#getChildrenFor(id),我就没事了。但如果我打电话:
Parent parent = service.findById( id );
Set<Child> children = service.getChildrenOf( parent );
然后 hibernate 抛出一个异常,表示没有与当前事务关联的 session ,因此它无法迭代 #getChildren 的延迟加载的 PersistentSet。
现在我不是 JPA 或 Spring 专家,所以也许这是有意的行为。如果是的话你能告诉我为什么吗?我是否需要创建一个不是要公开的服务的实体的 DTA,然后让我的客户使用它而不是该实体?我认为,由于两个调用都使用相同的实体管理器引用,因此客户端应该能够进行这两个调用。
顺便说一句,这是使用 CTW“ Spring 配置”。 JpaTransactionManager 配置为横切,如下所示:
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txnMgr = new JpaTransactionManager();
txnMgr.setEntityManagerFactory( entityManagerFactory().getObject() );
// cross cut transactional methods with txn management
AnnotationTransactionAspect.aspectOf().setTransactionManager( txnMgr );
return txnMgr;
}
请告诉我我可以提供的任何其他信息来帮助解决此问题。
Spring XML 配置:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<context:spring-configured/>
<context:component-scan base-package="com.myapp"/>
</beans>
Spring Java 配置:
@Configuration
@PropertySource( "classpath:database.properties" )
public class DatabaseConfiguration {
@Value( "${database.dialect}" )
private String databaseDialect;
@Value( "${database.url}" )
private String databaseUrl;
@Value( "${database.driverClassName}" )
private String databaseDriver;
@Value( "${database.username}" )
private String databaseUser;
@Value( "${database.password}" )
private String databasePassword;
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setPersistenceUnitName( "persistenceUnit" );
factory.setDataSource( dataSource() );
Properties props = new Properties();
props.setProperty( "hibernate.dialect", databaseDialect );
factory.setJpaProperties( props );
return factory;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txnMgr = new JpaTransactionManager();
txnMgr.setEntityManagerFactory( entityManagerFactory().getObject() );
// cross cut transactional methods with txn management
AnnotationTransactionAspect.aspectOf().setTransactionManager( txnMgr );
return txnMgr;
}
@Bean
public DataSource dataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName( databaseDriver );
dataSource.setUrl( databaseUrl );
dataSource.setUsername( databaseUser );
dataSource.setPassword( databasePassword );
dataSource.setTestOnBorrow( true );
dataSource.setTestOnReturn( true );
dataSource.setTestWhileIdle( true );
dataSource.setTimeBetweenEvictionRunsMillis( 1800000 );
dataSource.setNumTestsPerEvictionRun( 3 );
dataSource.setMinEvictableIdleTimeMillis( 1800000 );
return dataSource;
}
}
POM:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.2</version>
<!-- NB: do not use 1.3 or 1.3.x due to MASPECTJ-90 and do not use 1.4 due to de`clare parents issue -->
<dependencies>
<!-- NB: You must use Maven 2.0.9 or above or these are ignored (see MNG-2972) -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<outxml>true</outxml>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
最佳答案
使用 JTA 事务时, session (即或多或少的实体管理器)会自动绑定(bind)到事务。这意味着事务 T1 期间获取的实体是在与 T1 绑定(bind)的实体管理器/ session 中获取的。
一旦提交 T1,entityManager/session 就不再附加到任何事务(因为 T1 已完成)。
当您的客户这样做时:
Parent parent = service.findById( id );
Set<Child> children = service.getChildrenFor( parent );
parent
在 T1 期间获取,因此它绑定(bind)到与 T1 绑定(bind)的 entityManager
(我们称之为 EM1)。但 T1 已完成(当 findById
返回时已提交)。
由于 getChildrenFor
带有 @Transactional
注释:txManager 启动了一个新的 tx(即 T2)。这将创建一个与 T2 关联的新实体管理器(即 EM2)。但 parent
属于 EM1,并且 EM1 仍未绑定(bind)到任何正在运行的交易。
要解决您的问题,您可以调整此方法的代码:
@Transactional
public Set<Child> getChildrenFor( Parent parent ) {
Parent mergedParent = entityManager.merge(parent);
return Collections.unmodifiableSet( new HashSet<>( mergedParent.getChildren() ) );
}
调用merge
将会
Merge the state of the given entity into the current persistence context.
(请注意,持久化上下文是与当前entityManager关联的存储)
mergedParent
现在属于 EM2,并且 EM2 绑定(bind)到当前运行的 T2,因此调用 mergedParent.getChildren()
不会失败。
关于merge
的重要说明:重要的是要注意merge
返回一个新实例并且不' t 触摸参数中传递的实例。在使用 JPA 时,认为合并
修改实例是一个非常常见的错误/误解。
此时,我希望您明白,当您在同一个 tx 中获取父级和子级(调用 getChildrenFor( Long id )
)时,无需合并,因为(父级和子级) Children) 属于同一个entityManager。
关于java - 多个JTA事务: no session associated with the current transaction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14591287/
我有一个 jQuery 日期选择器。我想将默认日期设置为“当前月份、当前日期(当前年份-18)”,但在设置 defaultDate 属性时遇到问题。显示的默认年份是 1920 年,据说是 1995 年
我有下面的 C 程序来实现升序链表。问题出在 buildList() 函数中,因此您可以忽略除 main() 和 buildList() 之外的其他函数。 #include #include stru
嗯,想象一下 current.txt 文件: asdf base.txt 文件: asdf 其他.txt文件: asdf 当我进行三向 merge 时 git merge-file current.t
我试图在鼠标悬停时生成一个 :after 伪元素。例如: .email{ width:100px; overflow:hidden; text-overflow:ellipsi
为什么 $('a.current').removeClass('current'); 不适用于此 jquery 选项卡? http://jsfiddle.net/laukstein/ytnw9/8/
我正在创建一个应用程序(Outlook 的 Office 加载项) 我遇到的问题是更新我的屏幕。我知道我需要调用 Dispatcher,但是它在我的 ViewModel 中始终为 null p
我为客户开发网络和移动应用程序。在我当前的架构中,许多资源在 Web 访问和移动访问之间共享。 aspx 页面可以显示在网络上,也可以在移动应用程序中调用 WebView 。我的问题是: WebOpe
我通过调用 IEnumerable.GetEnumerator() 得到了一个枚举器,然后我称它为MoveNext()直到它返回false,然后访问它的Current属性(property)。令我惊讶
我正在尝试动态查找当前运行的函数(此函数)的名称,即 (defun my-func () (remove-hook 'some-hook this-function) (do-
阅读了短语 "The current SynchronizationContext is a property of the current thread" correct" ,我有点懵了…… 在 V
集成 IOS STRIPE TERMINAL SDK对于BBPOS Chipper 2X BT使用 swift 。我们已经开发并测试了该系统,并且运行良好。但是当我们将它交给其他国家的客户时,他们收到
当我在训练期间编写的类上实现 IEnumerable 和 IEnumerator 时,我注意到我需要为属性“Current”指定两个实现。 public class PeopleEnumerator
我原以为对实现了 IEnumerable 的空集合执行以下代码会抛出异常: var enumerator = collection.GetEnumerator(); enumerator.MoveNe
应Application.Current.Shutdown()不用作关闭 WPF 应用程序的最佳实践? 我有一个小的多窗口应用程序,“关机”似乎对我所有的退出命令都很好。但是,我被告知要始终使用 Ap
在 XPath 1.0 中,有一个函数 current() 可以派上用场,当我根据我当时所在的节点引用 XML 中其他地方的节点时。我的 XML 具有如下结构:
在 MVC 中,这两者有什么区别? 它们看起来相同,甚至返回相同的类型/类System.Web.Security.RolePrincipal,但有一些微妙之处。 例如。当针对通过 ClaimsPrin
这个问题在这里已经有了答案: What is the difference between an App and Application in c#.net? (1 个回答) 关闭 7 年前。 这两
我正在为我的团队开发一个代码生成器 (VSIX),在我与 VSIX 可扩展性框架作斗争之后,我打算使用 Roslyn 作为基础引擎。 我的代码生成器目前能够为解决方案生成一个新的 csproj,并且能
为什么 $('a.current').parent('li').addClass('current'); 和 $(this).hasClass('current')。 parent('li').add
当我使用 Xcode 调试我的 iOS 程序时,gdb 将其显示在控制台 View 上,并且没有发生任何错误。 我只想知道输出“Current language: auto; currently ob
我是一名优秀的程序员,十分优秀!