我正在实现基于spring 3.2.8,jpa2.1和hibernate 4.3.5的Web应用程序。我想知道如何阻止hibernate缓存特定的Named Stored Procedure Query
。
我尝试过entityManager.clear(),但我认为它会清除所有缓存的实体值,因此它不是最佳解决方案!!
注意:我使用@NamedStoredProcedureQueries
来定义存储过程并通过它来调用它
获得结果的entityManager.createNamedStoredProcedureQuery()
方法
已添加:
表人:
person{p# as PK, ...}
表 person_value :
person_value{pv# as PK, p# as foreign key from table person, ...}
查看 view1 :
select *,check_value(dbo.person.p#) as has_value from person
功能 check_value(输入):
如果在person_value中有记录,并且p#等于输入,则返回1.
存储过程 SPS_VIEW1 :
select * from view1
where p#=@p#
sql server视图的实体类 view1 :
@Entity
@Table(name = "view1")
@NamedStoredProcedureQueries(
@NamedStoredProcedureQuery(name = "getV1Records", procedureName = "SPS_VIEW1",
resultClasses = View1.class,
@parameters = {@StoredProcedureParameter(name = "p#", type = String.class)))
public class View1{
@Id
@Column(name = "p#")
private String personId;
@Column(name = "hasValue")
private boolean value;
<getters and setters>
}
服务类:
@Service("personService")
public class PersonService() {
...
private EntityManager entityManager;
<getters and setters>
...
public List<View1> getAll(String pno) {
SqlParameterValue p = new SqlParameterValue(new SqlParameter("p#", Types.VARCHAR), pno);
StoredProcedureQuery spq = entityManager.createNamedStoredProcedureQuery("getV1Records");
spq.setParameter(p.getName(), p.getValue());
return list;
}
}
控制器类:
@Controller("PersonController")
public class PersonController {
...
@Autowired
private PersonService personService;
...
@RequestMapping("/person")
public personInfo(HttpServletRequest request) {
String pno = request.getParameter("pno");
ModelAndView mv = new ModelAndView("person");
List<View1> list = personService.getAll(pno);
mv.addObject("view1_list", list);
return mv;
}
...
}
当我使用 p#致电getAll()
时,例如第一次在我的控制器中'p14521',在表person_value 中没有p#'p14521'的记录,它会正常工作,一切正常,但是当我使用 p#'p14521'向getAll()
不会发生任何事情到输出列表。似乎缓存了查询的输出列表。
答案 0 :(得分:0)
您可以通过指定以下提示告诉hibernate不要从缓存中获取: -
hints = { @QueryHint(name = "org.hibernate.cacheable", value = "false") },
试试这个: -
@NamedStoredProcedureQueries({
@NamedStoredProcedureQuery(
name="proc1",
resultClass=.....class,
hints = { @QueryHint(name = "org.hibernate.cacheable", value = "false") },
procedureName="Proc1",
parameters={...
),
@NamedStoredProcedureQuery(
name="proc2",
resultClass=.....class,
hints = { @QueryHint(name = "org.hibernate.cacheable", value = "false") },
procedureName="Proc2",
parameters={...
))
答案 1 :(得分:0)
默认情况下,Hibernate不会缓存查询结果。您必须启用二级缓存查询,并指示缓存当前正在执行的查询。
Hibernate的默认第一级缓存是一个实体缓存,无论何时加载实体,它都会启动:查找/加载或HQL /条件查询。
我认为您的存储过程结果根本不会被缓存。
您的问题可能与您的存储过程未触发的Hibernate AUTO flush mode有关。
在执行存储过程之前触发手动刷新:
em.flush();
此外,您没有在getAll方法中调用查询getResultList:
所以它应该是这样的:
em.flush();
return spq.getResultList();