猿问

当使用getOne和findOne方法时Spring Data JPA

我有一个用例,其中它调用以下内容:


@Override

@Transactional(propagation=Propagation.REQUIRES_NEW)

public UserControl getUserControlById(Integer id){

    return this.userControlRepository.getOne(id);

}

观察@Transactionalhas具有Propagation.REQUIRES_NEW,并且存储库使用getOne。当我运行该应用程序时,我收到以下错误消息:


Exception in thread "main" org.hibernate.LazyInitializationException: 

could not initialize proxy - no Session

...

但是,如果我改变getOne(id)的findOne(id)一切工作正常。


顺便说一句,在用例调用getUserControlById方法之前,它已经调用了insertUserControl方法


@Override

@Transactional(propagation=Propagation.REQUIRES_NEW)

public UserControl insertUserControl(UserControl userControl) {

    return this.userControlRepository.save(userControl);

}

这两种方法都是Propagation.REQUIRES_NEW,因为我正在执行简单的审核控制。


我使用该getOne方法是因为它是在JpaRepository接口中定义的,并且我的Repository接口从那里扩展,所以我正在使用JPA。


该JpaRepository接口扩展自CrudRepository。该findOne(id)方法在中定义CrudRepository。


我的问题是:


为什么该getOne(id)方法失败?

什么时候应该使用该getOne(id)方法?

我正在使用其他存储库,并且都使用该getOne(id)方法并且都正常工作,只有当我使用Propagation.REQUIRES_NEW时,它才会失败。


根据getOne API:


返回对具有给定标识符的实体的引用。


根据findOne API:


通过其ID检索实体。


3)什么时候应该使用该findOne(id)方法?


4)建议使用哪种方法?


提前致谢。


慕标琳琳
浏览 1521回答 3
3回答

慕的地6264312

1.为什么getOne(id)方法失败?请参阅文档中的本节。你重写已经到位交易可能导致该问题。但是,如果没有更多信息,则很难回答。2.什么时候应该使用getOne(id)方法?没有挖掘到Spring数据JPA的内部,差别似乎是用来检索实体的机制。如果您在“ 另请参见 ” 下查看JavaDoc:getOne(ID)See Also:EntityManager.getReference(Class, Object)似乎此方法只是委托给JPA实体管理器的实现。然而,该文档为findOne(ID)没有提到这一点。线索也在存储库的名称中。 JpaRepository是JPA专用的,因此可以根据需要将调用委派给实体管理器。 CrudRepository是不可知使用的持久性技术。看这里。它用作多种持久性技术(如JPA,Neo4J等)的标记接口。所以这是不是一个真正的“差异”的两种方法供您使用的情况下,它只是findOne(ID)比更专业更通用getOne(ID)。您使用哪一个取决于您和您的项目,但是我个人会坚持使用,findOne(ID)因为这会使您的代码减少实现的特定性,并且为将来无需过多重构就可以迁移到MongoDB等之类打开大门。
随时随地看视频慕课网APP
我要回答