Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.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
Spring 单个事务中的ArgumentResolver?_Spring_Hibernate_Spring Mvc_Transactions - Fatal编程技术网

Spring 单个事务中的ArgumentResolver?

Spring 单个事务中的ArgumentResolver?,spring,hibernate,spring-mvc,transactions,Spring,Hibernate,Spring Mvc,Transactions,我想知道是否有一种方法可以将@PathVariables或@modeldattributes的所有参数解析器封装到一个事务中?我们已经在使用OEMIV过滤器,但是spring/hibernate产生了太多的事务(如果它们没有包装在服务类中,则每个选择一个事务,例如pathvariable解析器就是这样) 虽然系统仍然相当快,但我认为这是不必要的,也与体系结构的其余部分不一致 让我解释一下: 假设我有一个包含两个实体的请求映射,并且转换基于StringToEntityConverter 如果我们支

我想知道是否有一种方法可以将
@PathVariables
@modeldattributes
的所有参数解析器封装到一个事务中?我们已经在使用OEMIV过滤器,但是spring/hibernate产生了太多的事务(如果它们没有包装在服务类中,则每个选择一个事务,例如pathvariable解析器就是这样)

虽然系统仍然相当快,但我认为这是不必要的,也与体系结构的其余部分不一致

让我解释一下:

假设我有一个包含两个实体的请求映射,并且转换基于
StringToEntityConverter

如果我们支持GET:
http://localhost/app/link/User_231/Item_324

@RequestMapping("/link/{user}/{item}", method="POST")
public String linkUserAndItem(@PathVariable("user") User user, @PathVariable("item") Item item) {
    userService.addItem(user, item);
    return "linked";
}


@Converter
// simplified
public Object convert(String classAndId) {
    return entityManager.find(getClass(classAndId), getId(classAndId));
}
UserService.addItem()
方法是事务性的,因此这里没有问题

但是:

实体转换器在调用
控制器
之前根据数据库解析用户和项目,从而创建两个选择,每个选择都在自己的事务中运行。然后我们有了
@modeldattribute
方法,这些方法可能还会再次发出一些选择,每个方法都会产生一个事务

这就是我想要改变的。我想创建一个只读事务

我找不到任何方法来拦截/监听/等等。。。借助于弹簧

首先,我想覆盖
RequestMappingHandlerAdapter
,但解析程序调用在
invokeHandleMethod
方法中“隐藏”得很好

ModelFactory
不是Springbean,因此我也不能编写拦截器

因此,目前我只看到完全替换
RequestMappingHandlerAdapter
的方法,但我确实希望避免这种情况


还有想法

对我来说,这似乎是设计上的失败。OEMIV通常是你做错了的标志™.

相反,要:

@RequestMapping("/link/User_{userId}/Item_{itemId}", method="POST")
public String linkUserAndItem(@PathVariable("userId") Long userId,
                              @PathVariable("itemId") Long itemId) {
    userService.addItem(userId, itemId);
    return "linked";
}

服务层负责获取和操作实体。这种逻辑不属于控制器。

虽然我可以理解您的OEMIV观点,但我不得不不同意。人们赞成或反对这种做法的可能性大约为50%;)对于我和我的团队来说,请求本身就是一个工作单元。要么失败,要么成功。但这不是问题的重点。我们只是用来呈现页面的OEMIV过滤器。如果出现错误,这仍然是正确处理的。我坚定地支持“观点应该是愚蠢的”阵营。将视图实际需要的所有内容作为简单变量(最好是字符串)传入。然后您的视图是精简的,控制器是精简的,服务调用是事务性的,并且执行真正的工作。考虑到SpringCore中缺乏支持,您显然在做一些非标准的事情;也许你应该重新考虑这一点。@MartinFrey我想到了一个可能的解决方案,它不涉及改变一切:你可以使用
spring aop
在你的控制器方法上做一个切入点,并在那里手动启动一个事务,或者可能用
@Transactional
注释aop方法。谢谢你的输入。到目前为止,我认为我们没有做错什么。modelattribute方法使用服务和存储库解析实体。然后,它将模型传递给requestmapping方法,该方法使用服务完成它的一部分。只是每个modelattribute方法都可能使用一个需要事务的服务调用。因此,我希望将modelattributeresolver整体包装,而不是逐个包装。这就是spring不支持它的地方,例如,我还找不到AOP切入点。请尝试类似于
@Transactional@Around(“myapp.Controller.method()”)
的方法。