- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个调用以下内容的用例:
@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public UserControl getUserControlById(Integer id){
return this.userControlRepository.getOne(id);
}
观察 @Transactional
有 Propagation.REQUIRES_NEW 并且存储库使用 getOne。当我运行该应用程序时,我收到以下错误消息:
Exception in thread "main" org.hibernate.LazyInitializationException:
could not initialize proxy - no Session
...
但是如果我通过 findOne(id)
更改 getOne(id)
一切正常。
顺便说一句,就在用例调用getUserControlById 方法之前,它已经调用了insertUserControl 方法
@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public UserControl insertUserControl(UserControl userControl) {
return this.userControlRepository.save(userControl);
}
这两种方法都是Propagation.REQUIRES_NEW,因为我正在做一个简单的审计控制。
我使用 getOne
方法,因为它是在 JpaRepository 中定义的接口(interface)和我的 Repository 接口(interface)从那里扩展,当然我正在使用 JPA。
JpaRepository 接口(interface)扩展自 CrudRepository .findOne(id)
方法在 CrudRepository
中定义。
我的问题是:
getOne(id)
方法失败?getOne(id)
方法?我正在使用其他存储库,并且都使用 getOne(id)
方法并且一切正常,只有当我使用 Propagation.REQUIRES_NEW 时才会失败。
根据 getOne API:
Returns a reference to the entity with the given identifier.
根据findOne API:
Retrieves an entity by its id.
什么时候应该使用 findOne(id)
方法?
推荐使用什么方法?
最佳答案
T findOne(ID id)
(旧 API 中的名称)/Optional<T> findById(ID id)
(新 API 中的名称)依赖于 EntityManager.find()
执行实体预先加载。
T getOne(ID id)
依赖EntityManager.getReference()
执行实体延迟加载。所以为了保证实体的有效加载,需要在实体上调用方法。
findOne()/findById()
确实比getOne()
更清晰易用.
所以在大多数情况下,喜欢 findOne()/findById()
在 getOne()
.
至少从 2.0
版本,Spring-Data-Jpa
已修改 findOne()
.
以前,它是在 CrudRepository
中定义的界面为:
T findOne(ID primaryKey);
现在,单findOne()
您将在 CrudRepository
中找到的方法是QueryByExampleExecutor
中定义的哪一个界面为:
<S extends T> Optional<S> findOne(Example<S> example);
最终由 SimpleJpaRepository
实现, CrudRepository
的默认实现界面。
此方法是通过示例搜索进行查询,您不希望将其作为替代方法。
事实上,具有相同行为的方法在新API中仍然存在,只是方法名称已更改。
它从 findOne()
重命名至 findById()
在 CrudRepository
界面:
Optional<T> findById(ID id);
现在它返回一个 Optional
.预防哪个还不错NullPointerException
.
所以,现在实际的选择是 Optional<T> findById(ID id)
和 T getOne(ID id)
.
1) Optional<T> findById(ID id)
javadoc声明它:
Retrieves an entity by its id.
当我们查看实现时,我们可以看到它依赖于 EntityManager.find()
进行检索:
public Optional<T> findById(ID id) {
Assert.notNull(id, ID_MUST_NOT_BE_NULL);
Class<T> domainType = getDomainClass();
if (metadata == null) {
return Optional.ofNullable(em.find(domainType, id));
}
LockModeType type = metadata.getLockModeType();
Map<String, Object> hints = getQueryHints().withFetchGraphs(em).asMap();
return Optional.ofNullable(type == null ? em.find(domainType, id, hints) : em.find(domainType, id, type, hints));
}
这里 em.find()
是一个 EntityManager
方法声明为:
public <T> T find(Class<T> entityClass, Object primaryKey,
Map<String, Object> properties);
它的 javadoc 声明:
Find by primary key, using the specified properties
因此,检索加载的实体似乎是预期的。
2) 而 T getOne(ID id)
javadoc状态(重点是我的):
Returns a reference to the entity with the given identifier.
事实上,reference 术语确实是白板,JPA API 没有指定任何 getOne()
方法。
因此,要了解 Spring 包装器的作用,最好的办法就是研究其实现:
@Override
public T getOne(ID id) {
Assert.notNull(id, ID_MUST_NOT_BE_NULL);
return em.getReference(getDomainClass(), id);
}
在这里 em.getReference()
是一个 EntityManager
方法声明为:
public <T> T getReference(Class<T> entityClass,
Object primaryKey);
幸运的是,EntityManager
javadoc 更好地定义了它的意图(重点是我的):
Get an instance, whose state may be lazily fetched. If the requested instance does not exist in the database, the EntityNotFoundException is thrown when the instance state is first accessed. (The persistence provider runtime is permitted to throw the EntityNotFoundException when getReference is called.) The application should not expect that the instance state will be available upon detachment, unless it was accessed by the application while the entity manager was open.
因此,调用 getOne()
可能会返回延迟获取的实体。
在这里,惰性抓取指的不是实体之间的关系,而是实体本身。
这意味着如果我们调用 getOne()
然后关闭 Persistence 上下文,实体可能永远不会加载,因此结果真的不可预测。
例如,如果代理对象被序列化,您可以获得 null
作为序列化结果引用,或者如果在代理对象上调用方法,则会出现异常,例如 LazyInitializationException
被抛出。
所以在这种情况下,抛出 EntityNotFoundException
这是使用 getOne()
的主要原因处理数据库中不存在的实例,因为当实体不存在时可能永远不会执行错误情况。
在任何情况下,为确保其加载,您必须在 session 打开时操作实体。您可以通过调用实体上的任何方法来实现。
或者更好的替代用途 findById(ID id)
而不是。
最后,给 Spring-Data-JPA 开发人员两个问题:
为什么不为 getOne()
提供更清晰的文档? ?实体懒加载真的不是一个细节。
为什么要介绍getOne()
包裹 EM.getReference()
?
为什么不简单地坚持包装方法:getReference()
?这个EM方法真的很讲究getOne()
传达了如此简单的处理。
关于jpa - 当使用 getOne 和 findOne 方法时 Spring Data JPA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49319017/
只是想知道这些结构之间有什么区别(text、data、rodata、bss 等)在链接描述文件中: .data : { *(.data) } .data : { *(.data*) }
Data 定义为其核心功能之一 gfoldl : gfoldl :: (Data a) => (forall d b. Data d => c (d -> b) -> d -> c b)
以下之间有什么区别:data-sly-use、data-sly-resource、data-sly-include 和 数据-sly-模板?我正在阅读 Sightly AEM 上的文档,我非常困惑。
我有一个 Spring Boot、Spring Data JPA (hibernate) Web 应用程序,并且想引入文本搜索功能。 我理解以下内容 hibernate search 或 spring
我不知道我的代码有什么问题。我读了其他有同样问题的人的一些问题,但没有找到答案。当我尝试编译时出现以下错误: ||In function 'main':| |35|error: expected ex
我不太确定为什么会收到此错误或其含义。我的数据框称为“数据”。 library(dplyr) data %>% filter(Info==1, Male==1) %>% lm(CFL_
我一直在 GitHub 等更现代的网站上看到这些属性,它们似乎总是与自定义的弹出窗口一致,如 title 属性。 Option 1 Option 2 Option 3 Option 4 我在 HTML
如何用 iCloud Core Data 替换我现有的 Core Data?这是我的持久商店协调员: lazy var persistentStoreCoordinator: NSPersistent
我一直在 GitHub 等更现代的网站上看到这些属性,它们似乎总是与自定义的弹出窗口一致,如 title 属性。 Option 1 Option 2 Option 3 Option 4 我在 HTML
我正在通过 this project 在 Android 上摆弄 node.js ,我需要一种方法将 js 文件部署到私有(private)目录(以隐藏源代码,防止用户篡改),该目录也物理存在于文件系
大家好我有点沮丧,所以我希望得到一些帮助。我的项目在 SwiftUI 中。我想使用图像选择器将图像保存到 Core Data。我实现了让 ImagePicker 工作,但我正在努力转换 Image -
我有以下数据和代码: mydf grp categ condition value 1 A X P 2 2 B X P 5
我一直在努力解决这个问题,但我根本找不到任何解决问题的方法。希望这里有人可以提供帮助。 我正在尝试为具有以下结构的某些数据创建个人选择矩阵: # A tibble: 2,152 x 32 a
我了解 Data.Map.Lazy 和 Data.Map.Strict 是不同的。但是,当您导入 Data.Map 时,您究竟导入了什么:严格的、惰性的还是两者的组合? 最佳答案 懒人。看着docs
我正在开发一个 C 程序,用于从 BerkeleyDB DBTree 数据库中提取数据值与特定模式匹配的记录。我创建数据库,打开它,将键的 DBT 和数据的另一个 DBT 清零,将 DBT 标志设置为
所以我有以下成员(member)历史表 User_ID | Start date | End Date | Type(0-7) | ---------------------------
随着最近推出的包dataframe ,我认为是时候正确地对各种数据结构进行基准测试,并突出每种数据结构的优势。我不是每个人的不同优势的专家,所以我的问题是,我们应该如何对它们进行基准测试。 我尝试过的
我有来自 API 的数据,但无法将数组中的数据设置为 vue.js 中的 this.data这是来自 API 的数据(JSON) 你能告诉我这个语法吗 {"id":1613, "name_org":"
在 Vue.js到目前为止,我已经找到了两种定义数据的方法:data: {} 和 data() { return; }. data: { defaultLayout: 'default' }
我正在研究Spring Data Rest Services,并在自定义拦截器中遇到一些问题。之前我使用spring-data-rest-webmvc 2.2.0并以以下方式添加了拦截器。 publi
我是一名优秀的程序员,十分优秀!