我试图了解JPA的工作原理。据我所知,如果你持有一个实体,该对象将保留在内存中,直到应用程序关闭。这意味着,当我查找以前持久化的实体时,将不会对数据库进行查询。假设没有进行插入,更新或删除,如果应用程序运行的时间足够长,则其中的所有信息可能会持久化。这是否意味着在某些时候,我将不再需要数据库?
修改
我的问题不在于数据库。我确信无法从应用程序外部修改数据库。我自己管理事务,所以数据一提交就会存储在数据库中。我的问题是:我提交后实体会发生什么?它们是否保存在内存中并像缓存一样?如果是这样,他们在那里待了多久?提交persist
后,我会进行select
查询。这个选择应该返回我之前持久化的对象。该对象是从内存中获取的,还是应用程序会查询数据库?
答案 0 :(得分:5)
不是真的。想一想。
您的应用程序可能不是唯一使用该数据库的东西。如果一个实体被持久存储并存储在内存中,那么你怎么能确定,一小时之后,它不会被其他方式改变?如果发生这种情况,您将获得可能损害应用程序逻辑的陈旧数据。
将数据存储在内存中并希望一切顺利不会带来任何好处。这就是为什么存储在数据库中的数据是您的主要信息来源的原因,您应该每次都查询它,除非您绝对确定数据子集不会发生变化。
答案 1 :(得分:4)
当您将实体持久化为实体时,它会将其添加到持久性上下文中,该上下文的作用类似于第一级缓存(这是内存中)。实际持久发生时取决于您是使用容器管理的事务还是自己处理事务。只要事务没有被提交,实体实例就会存在于内存中,当它被保存到数据库或XML等时,实体实例将存在于内存中。
答案 2 :(得分:3)
持久性意味着短期:您可以关闭应用,数据也不会丢失。
要实现这一点,您需要一个数据库或某种类型的保存数据,以便在关闭应用程序时不会丢失数据。
答案 3 :(得分:3)
“持久化”实体意味着将其实际保存在数据库中。当然,JPA在持久化上下文中维护内存中的一些实体信息(这高度依赖于配置和编程实践),但在某些时候信息将存储在数据库中 - 例如,当事务提交时,或者可能(但不一定)在flush()
或merge()
操作之后。
答案 4 :(得分:3)
JPA不能仅使用持久性上下文(L1缓存)或显式缓存(L2缓存)。它总是需要与数据源结合使用,而这个数据源通常指向一个持久存储到稳定存储的数据库。
因此,只要事务(JPA持久化操作所需)未提交,实体就在内存中。之后,它将发送到数据源。
如果事务管理器是事务范围的(“正常”情况),那么L1缓存(持久性上下文)将关闭,并且实体不再存在。如果L1缓存以某种方式困扰您,您可以明确地管理它。有清除它的操作,您可以将读取操作(不需要事务)与写入操作分开。如果在读取时没有活动事务,则没有持久性上下文,实体永远不会被附加,因此永远不会被放入此L1缓存中。
但是,当事务提交并且其中的实体仍然可用于整个应用程序时,L2缓存不会被清除。必须明确配置此L2缓存,并且您作为应用程序开发人员必须指明应在其中缓存哪些实体。通过供应商特定的机制(例如JBoss Cache,Infinispan),您可以对缓存的实体数量进行最大化,并设置/定义所谓的驱逐策略。
当然,没有什么可以阻止你让数据源指向内存嵌入式数据库,但这不在JPA的知识范围内。
答案 5 :(得分:3)
如果要在提交后保留实体并选择查询,则需要使用查询缓存。只是谷歌在那个期限,你应该清楚。