Quanto se trabalha com entidades JPA, sabemos que o tempo de sincronização dos dados contidos no EntityManager com os dados armazenados no banco, é pré-definido, então em muitos casos quando uma consulta não traz o resultado esperado no instante em que a query foi executada, pode ser que exista cache agindo sobre essa consulta.
Outros exemplos:
- Quando você faz uma inserção diretamente no banco ( sem a execução de um merge ou persist através do E.M. ).
- Quando existe a execução de uma stored procedure ou package, que faz inserção de dados em banco ( mesmo se esta for chamada como Native Query no E.M. já que o executor será o próprio banco de dados ).
Para solucionar esse problema, utilizamos Hints, esses são propriedades setadas na própria query antes da mesma ser executada no EntityManager, esses hints podem variar de acordo com o provider utilizado.
Esses são detalhes muito importantes que no caso do aprendizado prático, acaba-se deixando de lado, mas é bom sabermos que CACHE faz parte de JPA e precisa ser tratado com determinada importância. Traz grandes benefícios de performance e robustêz à sua aplicação.
Podemos citar os principais providers e seus respectivos hints:
IBM WEBSPHERE:
com.ibm.websphere.jpa.default.provider
ORACLE TOPLINK:
oracle.toplink.essentials.PersistenceProvider
HIBERNATE:
org.hibernate.ejb.HibernatePersistence
Como esse é um vasto assunto e estamos falando de cache, vamos citar os principais Hints para refresh:
************************************
--- Toplink
** Por anotação
Example: JPA Query API
import oracle.toplink.essentials.config.HintValues;
import oracle.toplink.essentials.config.TopLinkQueryHints;
query.setHint(TopLinkQueryHints.REFRESH, HintValues.TRUE);
Example: @QueryHint
import oracle.toplink.essentials.config.HintValues;
import oracle.toplink.essentials.config.TopLinkQueryHints;
@QueryHint(name=TopLinkQueryHints.REFRESH, value=HintValues.TRUE);
** no orm.xml
<entity-mapping<
...
<named-query name="findEmployeesWithName">
<query>SELECT e FROM Employee e WHERE e.name LIKE :empName</query>
<hint name="toplink.refresh" value="true" />
<hint name="toplink.refresh.cascade" value="CascadeAllParts" />
</named-query>
...
<entity-mapping>
** no código
//query ... my query..
query.setHint("toplink.refresh", true);
query.setHint("toplink.refresh.cascade", "CascadeAllParts");
Obs: veja que nesse caso do toplink tanbém existe a propriedade cascade, que faz um refresh tanbém de outros objetos relacionadas com sua Entity.
Leitura:
Mais hints oracle toplink
************************************
---- Eclipselink
*** Anotação
@NamedQuery(name="findEmployeeNoCache",
query="SELECT e FROM Employee e WHERE e.id = :empId",
hints={@QueryHint(name="eclipselink.cache-usage",
value="DoNotCheckCache")})
*** orm.xml
<entity-mapping>
...
<named-query name="findEmployeesWithName">
<query<SELECT e FROM Employee e WHERE e.name LIKE :empName</query>
<hint name="eclipselink.cache-usage" value="DoNotCheckCache"/>
</named-query>
...
<entity-mapping>
Leitura
Documento completo direto do site da IBM
Tudo o que você precisa saber sobre Query Hints
************************************
---Hibernate
***** No código:
query.setHint("org.hibernate.cacheMode", CacheMode.REFRESH)
ex: q.setHint("org.hibernate.cacheable", true);
Assinatura: org.hibernate.cacheable - true/false
Assinatura: org.hibernate.cacheMode - NORMAL / IGNORE / GET / PUT / REFRESH
Assinatura: org.hibernate.cacheRegion - String
Leitura:
Uma discussão muito boa sobre o assunto, site spring framework
2 comentários:
Muito obrigado pelas informações. resolveu um pepino grande que eu estava tendo aqui.
Essa cache ainda mata 1 do coração.
abraços.
Estava com dúvida nesse assunto.
Obrigado pelos esclarecimentos! =)
Postar um comentário