【发布时间】:2010-01-27 12:53:47
【问题描述】:
更新:澄清示例 我将举例说明正在发生的事情,以澄清我的 Spring + Hibernate 应用程序中的情况。 想象一下我有这两个实体(假设 getter 和 setter 也存在)
@Entity
public class Class1(){
private Integer id;
@OneToOne
private Class2 object2;
}
@Entity
public class Class2(){
private Integer id;
@OneToOne
private Class1 object2;
}
所以在我的数据库中,我有两个表来映射每个对象的每个实例。假设我在数据库中存储了这些对象:
- objectA(类 Class1):id = 1,object2 = objectB
- objectB(Class2 类):id = 2,object2 = objectA
- objectC(类 Class2):id = 3,object2 = null 这意味着 A 和 B 是链接的。假设现在我想将 objectA 链接到 objectC。这意味着我也必须删除 objectB 中的链接。
为此,我执行以下操作:
//I get the objectA from database
Class1 storedObjectA = myservice.find(objectAId);
//Now in storedObject1 I have the same as what it is stored as objectA
//I change only the object2 attribute of it
storedObject1.setObject2(objectC);
//I search again in the database to see objectA
Class1 reStoredObjectA = myservice.find(objectAId);
restoredObjectA 现在是:
- restoredObjectA (class= Class1) id = 1, object2 = objectC
虽然在数据库中有:
- restoredObjectA (class= Class1) id = 1, object2 = objectB
find 方法没有在数据库中搜索,虽然我禁用了查询和二级缓存,但我已经获得了先前的搜索。方法 find 只进入它在 entityManager.find(Class1.class, id) 上执行的 DAO 如何在数据库中进行第二次查找搜索?
谢谢
(完整解释)
你好,
我有一个使用 Spring 3 和 Hibernate 的应用程序。我有一个名为 Class1 的实体,它存储在数据库中。此实体具有指向另一个名为 Class2 的实体的 OneToOne 链接。 Class2 有另一个指向 Class1 的 OneToOne 链接,并且两个链接的唯一属性都设置为 true。
我的控制器中有以下代码:
//I have an object called dataFromUser which is instance of Class1 and
// it is obtained via @ModelAttribute annotation from a form
Integer id = dataFromUser.getId();
//I get correctly the stored object from the database
Class1 storedData = myService.find(id); //this will call em.find of hibernate
//I set to the stored data the attribute I want to change
storedData.setObject2();
//I save again the object
myService.save(storedData);
myService 中的方法 save 将使用实体管理器来持久化数据,但在此之前它将检查 Class1 对象和 Class2 对象之间的先前关联以将其删除,以防新的 Class2 对象已设置为 Class1 的实例。出于这个原因,我必须再次调用 find 方法来查看我的数据库中的内容
在服务中:
@Transactional
public void save(Class1 object1){
Class1 objectFromDB = myDAO.find(object1.getId());
// .... update the old object and save
}
问题是 Service 中的 objectFromDB 与我在控制器中执行 myService.find(id) 时不同。问题是它不是在数据库中寻找它,而是在内存中搜索。我知道是因为调用第二个 find() 方法时没有记录 SQL 语句。正如我对 storedData 对象所做的 setObject2() 一样,当我第二次调用 find 方法时,我得到的正是这个对象,并且数据库不包含它,因为它还没有被持久化。
我试图在我的配置中禁用缓存只是为了尝试,但它仍在发生。我有一个具有这种配置的 ehCache:
在 persistence.xml 我有这个属性(我已经将两个缓存都设置为 false):
<properties>
<!-- Hibernate 3.5.0 - try org.hibernate.cache.* package -->
<property name="hibernate.cache.provider_class"
value="net.sf.ehcache.hibernate.SingletonEhCacheProvider" />
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.cache.use_structured_entries" value="false" />
<property name="hibernate.format_sql" value="true" />
<!-- http://www.jroller.com/eyallupu/entry/hibernate_s_hbm2ddl_tool -->
<!-- create, create-drop, update, validate -->
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
在我的 ehcache.xml 中,我将 maxElementsInMemory 设置为 0 并将 overflowToDisk 设置为 false 以禁用它。
有什么办法可以避免这种情况吗?
谢谢。
【问题讨论】:
标签: hibernate spring jpa caching