如何防止NamedStoredProcedureQueries的hibernate 4缓存?

问题描述 投票:0回答:2

我正在实现一个基于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'向person_value添加记录时,现在有一个p#'p14521'的记录,再次调用getAll()输出列表不会发生任何事情。似乎缓存了查询的输出列表。

java spring hibernate jpa-2.1
2个回答
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={...
        ))

0
投票

Hibernate默认不缓存查询结果。您必须启用二级缓存查询,并指示缓存当前正在执行的查询。

Hibernate的默认第一级缓存是一个实体缓存,无论何时加载实体,它都会启动:查找/加载或HQL /条件查询。

我认为您的存储过程结果根本不会被缓存。

您的问题可能与您的存储过程未触发的Hibernate AUTO flush mode有关。

在执行存储过程之前触发手动刷新:

em.flush();

您也没有在getAll方法中调用查询getResultList:

所以它应该是这样的:

em.flush();
return spq.getResultList();
© www.soinside.com 2019 - 2024. All rights reserved.