【发布时间】:2011-10-12 08:18:15
【问题描述】:
我想运行一个查询,但结果应该是只读的。他们可能需要刷新,我不想刷新列表中的每个元素。我宁愿重新执行查询。因此,我希望所有结果都被分离。我现在做的是
List<Ent> lst = (List<Ent>)em.createQuery("FROM Ent").getResultList();
for (Ent l:lst) em.detach(l);
但对我来说似乎不对。
有更好的方法吗?
【问题讨论】:
我想运行一个查询,但结果应该是只读的。他们可能需要刷新,我不想刷新列表中的每个元素。我宁愿重新执行查询。因此,我希望所有结果都被分离。我现在做的是
List<Ent> lst = (List<Ent>)em.createQuery("FROM Ent").getResultList();
for (Ent l:lst) em.detach(l);
但对我来说似乎不对。
有更好的方法吗?
【问题讨论】:
将列表设为不可修改列表
List<Ent> lst = (List<Ent>)em.createQuery("FROM DeviceTree").getResultList();
lst =(List) Collections.unmodifiableCollection(lst );
List arl = new ArrayList();
arl.add("sk");
arl.add("sk2");
System.out.println("...."+arl);
arl =(List) Collections.unmodifiableCollection(arl);
try{
arl.add("sk3"); // it will give exception
}catch(exception ex
{ex.printStackTrace();} System.out.println("...."+arl);
【讨论】:
lst.get(0).setData(12);em.flush(); 将更改数据库。
也许 Hibernate 不支持 detach() 方法?您可以将实体复制到新的对象类型并将这些分离的实体返回给调用者。
StackOverflow 上有几个关于这个主题的类似问题:Detach an entity from JPA/EJB3 persistence context
【讨论】:
em.find(Ent.class,SomeIdAlreadyInEntityManager) 时它不会被刷新!
您似乎不希望返回的对象由持久性上下文管理。您可以考虑使用StatelessSession,因为使用StatelessSession返回的所有内容都处于分离状态,不受持久性上下文管理
StatelessSession session = sessionFactory.openStatelessSession();
List<Ent> lst = session.createQuery("FROM DeviceTree").getResultList(); //All the returned Ent are in the detached state
请注意,StatelessSession 没有实现一级缓存、二级缓存或查询缓存。您所做的一切都会导致立即执行 SQL 操作。您可以认为它就像使用普通 JDBC,只是您从映射的持久类中受益。
参考
【讨论】:
em.find(Ent.class,1);em.createQuery("UPDATE Ent SET data=17").executeUpdate();assertEquals(17,em.createQuery("FROM Ent WHERE id=1").getResultList().get(0).getData()); 通过。实体被缓存而不是从数据库中重新获取的事实并不完全清楚。