首页 文章

从Spring MVC @Controller获取集合时的HIbernate延迟加载行为

提问于
浏览
0

假设我在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 回答

  • 0

    好吧,我认为这个问题无法回答的原因是缺乏信息 . 当我保存SomeSubEntity的新实例时,我使用两个ID来定义它与模型的另一个实体的两个关系 .

    new SomeSubEntity(foo1Id, foo2Id);
    

    而SomeSubEntity的构造函数则执行以下操作:

    public SomeSubEntity(Integer idFoo1, Integer idFoo2) {
        this.setFoo1(new Foo1(idFoo1));
        this.setFoo2(new Foo2(idFoo2));
    }
    

    Foo1 / Foo2 的构造函数设置指定的ID而不设置任何其他ID .

    foo1Idfoo2Id 匹配 Foo1Foo2 两个实体的两个ID已经存在于数据库中并通过外键(和Hibernate映射)与 SomeSubEntity 相关,因此事务成功完成 .

    但是,似乎保留在会话中的 Foo1Foo2 实体与创建的实体相同(仅限ID,不从数据库更新),因此当我从它们获取属性时,将返回默认类值而不是实际值来自数据库的 Value .

    我使用来自数据库的托管实体解决了它,而不是创建一个具有匹配ID的新实体:

    public SomeSubEntity(Foo1 foo1, Foo2 foo2) {
        this.setFoo1(foo1);
        this.setFoo2(foo2);
    }
    
    new SomeSubEntity(
        foo1DAO.findById(idFoo1),
        foo2DAO.findById(idFoo2)
    );
    

    缺点是查询(显然)被触发到数据库 .

相关问题