假设我在Spring MVC _1262909中有以下方法:
@RequestMapping(value = "/list")
public ModelAndView renderView(@PathVariable("id") int id, @ModelAttribute("someForm") SomeForm someForm) {
SomeEntity someEntity = someEntityService.findById(id);
someForm.setEntity(someEntity);
someForm.setLstFromEntity(
new ArrayList<SomeSubEntity>(someEntity.getSomeSubEntities())
);
return new ModelAndView("someView", "someForm", someForm);
}
someEntityService
是 @Transactional
@Service
并且我正在获取它的集合是延迟加载的,所以认为提取会因为没有会话处于活动状态而失败是有意义的(我不确定这是否属实) . 虽然获取工作完美 .
但是,我有另一个注释为 @RequestMapping(value = "/save")
的方法,它执行保存并调用 renderView()
以将视图返回给客户端 . 在这种情况下, someEntity.findById(id)
返回实体但不激活对数据库的任何选择 . 填充所有字段但集合(PersistentBag)为空,因此实体不完整 .
几个问题:
-
会话真的关闭了吗?
-
在第二种情况下,这个实体来自哪里?
-
为什么集合被返回空?
1 回答
好吧,我认为这个问题无法回答的原因是缺乏信息 . 当我保存SomeSubEntity的新实例时,我使用两个ID来定义它与模型的另一个实体的两个关系 .
而SomeSubEntity的构造函数则执行以下操作:
Foo1
/Foo2
的构造函数设置指定的ID而不设置任何其他ID .foo1Id
和foo2Id
匹配Foo1
和Foo2
两个实体的两个ID已经存在于数据库中并通过外键(和Hibernate映射)与SomeSubEntity
相关,因此事务成功完成 .但是,似乎保留在会话中的
Foo1
和Foo2
实体与创建的实体相同(仅限ID,不从数据库更新),因此当我从它们获取属性时,将返回默认类值而不是实际值来自数据库的 Value .我使用来自数据库的托管实体解决了它,而不是创建一个具有匹配ID的新实体:
缺点是查询(显然)被触发到数据库 .