更新:清除示例 我将举例说明正在发生的事情,以澄清我的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;
}
所以在我的数据库中,我有两个表来映射每个对象的每个实例。假设我在数据库中存储了这些对象:
为此,我按照以下步骤进行操作:
//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现在是:
虽然在数据库中有:
方法find没有在数据库中搜索过,虽然我的查询和二级缓存已禁用,但我已经获得了之前的搜索。方法find只发送到它在entityManager.find上执行的DAO(Class1.class,id) 如何在数据库中进行第二次搜索?
由于
(完整解释)
您好,
我有一个使用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中,我设置为0 maxElementsInMemory,overflowToDisk设置为false以禁用它。
有没有办法避免这种情况?
感谢。
答案 0 :(得分:0)
我不确定我是否理解正确,但以防万一...
有两种加载对象的方法。如果对象不在当前内存上下文中,则会有所不同:
您似乎正在使用第二个,也许您可以尝试第一个,看看它是否解决了您的问题?
答案 1 :(得分:0)
//being em my EntityManager instance
Session session = (Session) em.getDelegate();
session.evict(plan);
//Now the find object will not get the object wich is in session
//but the one in database