Integração com Hibernate
O NEO possui algumas facilidades para a utilização do Hibernate. Além da configuração simplificada
ele também possui classes que facilitam ainda mais a utilização do Hibernate.
Configurando Hibernate
Existem duas formas de configurar o Hibernate. Através de uma configuração simplificada ou completa.
Na forma simplificada a configuração é feita pelo NEO,
na forma completa a configuração é feita via XML.
Configuração simplificada
A configuração simplificada está disponível apenas para os bancos de dados PostgreSQL,
Oracle e Microsoft SQL Server. Para os outros bancos de dados a configuração deverá ser feita através do arquivo XML de configuração dos beans.
Para utilizar configuração simplificada é necessário criar um arquivo chamado connection.properties e
colocá-lo no diretório /WEB-INF/classes.
Dica: Se estiver utilizando uma IDE como o eclipse. É só colocar o arquivo
na pasta dos fontes (geralmente src).
O arquivo connection.properties possui 5 parâmetros:
- jndi - Utilizado para fazer a configuração via jndi do dataSource
- driver - Classe do driver do banco de dados.
- url - url do banco de dados.
- username - nome de usuário do banco de dados
- password - senha do banco de dados
Através desse arquivo a configuração pode ser feita através de jndi ou jdbc.
Para JNDI é necessária a configuração do parâmetro jndi.
Para JDBC é necessária a configuração dos parâmetros driver, url, username e password.
Se as duas configurações forem informadas. Em ambientes J2EE a configuração JNDI será utilizada.
Em ambientes J2SE a configuração via JDBC será utilizada.
Exemplo de arquivo com JNDI informado:
jndi=java:/dataSourceJndiName
Exemplo de arquivo com o JDBC informado:
driver=org.postgresql.Driver
url=jdbc:postgresql://localhost/mydb
username=postgres
password=
O NEO detecta a presença do arquivo connection.properties e faz automaticamente toda a configuração
necessária para a conexão com o banco de dados e com o hibernate. Nenhum XML é necessário.
Configuração completa
Em determinadas situações uma configuração mais personalizada pode ser necessária. Nesse caso
deve ser utilizada a configuração completa do Hibernate. Essa configuração deve ser feita através de XML.
Nesse XML devem ser declarados os beans:
- dataSource - O DataSource fornece conexões com o banco de dados.
- sessionFactory - O sessionFactory é o que configura a sessão do hibernate.
- hibernateTemplate - Template que fornece métodos utilitários para executar queries.
- hibernateTransactionManager - Gerenciador de transações para o Hibernate.
- transactionTemplate - Template que facilita a utilização de transações na aplicação.
Já existem classes que implementam as interfaces necessárias para esses beans. A tabela abaixo mostra
quais classes são recomendáveis para a configuração de cada bean, além das dependências.
Bean |
Classe |
Dependência |
dataSource |
org.springframework.jdbc.datasource.DriverManagerDataSource
quando for
utilizar a configuração através de JDBC
org.springframework.jndi.JndiObjectFactoryBean
quando for
utilizar a configuração através de JNDI
|
- |
sessionFactory | br.com.linkcom.neo.hibernate.AnnotationSessionFactoryBean |
dataSource |
hibernateTemplate | org.springframework.orm.hibernate3.HibernateTemplate |
sessionFactory |
hibernateTransactionManager |
org.springframework.orm.hibernate3.HibernateTransactionManager |
dataSource, sessionFactory |
transactionTemplate | org.springframework.transaction.support.TransactionTemplate | hibernateTransactionManager |
Se algum bean não foi declarado mas as suas dependências foram, o NEO irá criar esse bean automaticamente.
Exemplo: Se o dataSource for declarado mas o sessionFactory não for declarado o NEO irá criar um sessionFactory
porque o dataSource de quem o sessionFactory depende foi informado.
Para efetuar a configuração desses beans deve ser utilizado o arquivo applicationConfig.xml que fica em /WEB-INF/.
Exemplo:
[JSP]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="hibernateTransactionManager"/>
</property>
</bean>
<bean id="hibernateTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/dataSourceJndiName</value>
</property>
</bean>
<bean id="sessionFactory" class="br.com.linkcom.neo.hibernate.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
</beans>
No bloco do bean sessionFactory deve ser informado o dialeto do hibernate de acordo com o banco de dados utilizado.
Se desejar utilizar uma configuração via JDBC substitua o bloco do bean dataSource pelo seguinte:
[JSP]
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost/mydb"/>
<property name="username" value="postgres"/>
<property name="password" value=""/>
</bean>
Importante: Não esqueça de copiar os arquivos JAR do NEO para a aplicação.
Configurando beans no Hibernate
Os beans do Hibernate são configurados utilizando
Hibernate Annotations.
Hibernate Annotations é um framework do Hibernate que permite que as informações sobre o mapeamento dos beans seja feita via
Annotations ao invés de XML. Em um ambiente apenas com o Hibernate Annotations além das anotações dos beans é necessário
configurar em algum lugar (geralmente um XML) quais são os beans anotados e que devem ser gerenciados pelo Hibernate. No NEO
essa configuração do XML não é necessária, ele irá detectar a presença dos beans e fazer o registro automático.
Só é necessário criar a classe e fazer a anotação que o bean será registrado no Hibernate. Veja o exemplo:
package teste;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Aluno {
private Integer id;
private String nome;
@Id
public Integer getId() {
return id;
}
public String getNome() {
return nome;
}
public void setId(Integer id) {
this.id = id;
}
public void setNome(String nome) {
this.nome = nome;
}
}
Importante: Para uma classe ser registrada pelo neo ela deve estar dentro de /WEB-INF/classes. As classes
dentro de arquivos JAR não são registradas.
Qualquer anotação do Hibernate Annotations é suportada pelo NEO. Para uma melhor utilização do
Hibernate Annotations veja a documentação no site do Hibernate.
Para uma melhor utilização do Hibernate Annotations no NEO alguns padrões devem ser seguidos. Veja os
exemplos de mapeamento abaixo:
package teste;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
@Entity
@SequenceGenerator(name = "sq_aluno", sequenceName = "sq_aluno")
public class Aluno {
private Integer id;
private String nome;
private List<Matricula> matriculas;
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="sq_aluno")
public Integer getId() {
return id;
}
@OneToMany(mappedBy="aluno")
public List<Matricula> getMatriculas() {
return matriculas;
}
public String getNome() {
return nome;
}
public void setId(Integer id) {
this.id = id;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setMatriculas(List<Matricula> matriculas) {
this.matriculas = matriculas;
}
}
-
@Entity
(linha 12)
Faz com que o bean seja registrado no Hibernate.
-
@SequenceGenerator
(linha 13)
Declara um Sequence generator, essa anotação é util para
banco de dados que utilizam um sequence para gerar a chave primária como o Postgresql.
-
@Id
(linha 20)
Declara o campo como primary key.
-
@GeneratedValue
(linha 21)
Indica que o campo deve ter o seu valor gerado.
No caso, pelo sequence generator sq_aluno.
-
@OneToMany
(linha 26)
Indica que o campo é um relacionamento um para muitos.
O atributo mappedBy informa qual é o campo na classe mapeada (Matricula) faz referencia para a
própria classe (Aluno).
package teste;
import java.sql.Date;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
@Entity
@SequenceGenerator(name = "sq_matricula", sequenceName = "sq_matricula")
public class Matricula {
private Integer id;
private Aluno aluno;
private Date data;
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="sq_matricula")
public Integer getId() {
return id;
}
@ManyToOne(fetch=FetchType.LAZY)
public Aluno getAluno() {
return aluno;
}
public Date getData() {
return data;
}
public void setAluno(Aluno aluno) {
this.aluno = aluno;
}
public void setData(Date data) {
this.data = data;
}
public void setId(Integer id) {
this.id = id;
}
}
-
@Entity
(linha 13)
Faz com que o bean seja registrado no Hibernate.
-
@SequenceGenerator
(linha 14)
Declara um Sequence generator, essa anotação é util para
banco de dados que utilizam um sequence para gerar a chave primária como o Postgresql.
-
@Id
(linha 21)
Declara o campo como primary key.
-
@GeneratedValue
(linha 22)
Indica que o campo deve ter o seu valor gerado.
No caso, pelo sequence generator sq_aluno.
-
@ManyToOne
(linha 27)
Indica que o campo é um relacionamento muitos para um.
- No mapeamento não foi necessário informar qual a coluna da tabela matricula
fazia relacionamento com a tabela aluno. Isso porque existe um padrão do Hibernate que é
o seguinte: O nome da coluna de mapeamento será o nome da propriedade + _id. Na tabela
matricula existe então o campo aluno_id. Para evitar ter que mapear as colunas utilize
esse padrão.
- Nas duas entidades foram utilizados surrogate keys, ou seja, campos que não tem significado
nenhum para a aplicação. Sempre utilize surrogate keys para a chave primária, isso evitará
muitos problemas.
- Utilize chaves primárias simples, com apenas um campo. O NEO não tem suporte para chaves
com mais de um campo. A utilização de chaves complexas irá dificultar o desenvolvimento.
- Sempre que fizer um relacionamento um para muitos (@OneToMany). Faça o relacionamento muitos
para um (@ManyToOne) inverso. Quando tiver um relacionamento muitos para um (@ManyToOne) o relacionamento
um para muitos (@OneToMany) é opcional.
- Para evitar consultas desncessárias ao banco de dados pelo Hibernate, utilize fetch=FetchType.LAZY
em mapeamentos @ManyToOne.
- Quando tiver relacionamentos muitos para muitos com uma tabela de ligação. Dê preferência
por um relacionamento muitos para um e um para muitos. Crie uma classe intermediaria que representa
a tabela de ligação. Isso facilita o desenvolvimento e evita que o Hibernate tenha comportamentos
indesejáveis em determinadas situações.
QueryBuilder
Construir queries de aplicações do mundo real não é muito trivial. Geralmente é utilizada a concatenação
de strings junto com blocos if para determinar se determinada condição deve ser adicionada na query de
acordo com os parâmetros passados. Além de gastar tempo montando o algorítmo de criação das queries
o código não fica organizado e de difícil manutenção. Para evitar o problema da criação de queries
o NEO possui a classe QueryBuilder.
Para utilizar o query builder é necessária ter uma referência para hibernateTemplate.
Veja o exemplo:
package teste;
import org.springframework.orm.hibernate3.HibernateTemplate;
import br.com.linkcom.neo.bean.annotation.Bean;
@Bean
public class ExecutaQuery {
private HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
}
Importante: Sempre utilize o HibernateTemplate do pacote org.springframework.orm.hibernate3
Criamos um bean ExecutaQuery e registramos utilizando @Bean. Criamos um atributo hibernateTemplate
e um setter. Qualquer método que criarmos agora no ExecutaQuery possuirá uma referência para hibernateTemplate
e então poderemos criar um QueryBuilder.
Vamos criar um método para retornar todos beans aluno que criamos anteriormente:
package teste;
import java.util.List;
import org.springframework.orm.hibernate3.HibernateTemplate;
import br.com.linkcom.neo.bean.annotation.Bean;
import br.com.linkcom.neo.persistence.QueryBuilder;
@Bean
public class ExecutaQuery {
private HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
public List<Aluno> findAll(){
return new QueryBuilder<Aluno>(hibernateTemplate)
.from(Aluno.class)
.list();
}
}
O queryBuilder pode ser parametrizado por um tipo genérico.
O queryBuilder também permite que apenas determinados campos sejam especificados na cláusula
select. Exemplo:
new QueryBuilder<Aluno>(hibernateTemplate)
.select("aluno.nome")
.from(Aluno.class)
.list();
Nesse caso os beans aluno retornados irão conter apenas o campo nome. Isso permite que apenas os dados
necessários sejam carregados. Quando os campos são determinados na cláusula do select o tipo de retorno
sempre será o mesmo da classe definida pelo método from.
O Hibernate não tem suporte para buscar apenas determinados campos do banco e mapear como objeto.
O NEO faz a tradução do resultado da query para os beans necessários. Se desejar cancelar o tradutor do NEO
utilize o método setUseTranslator(false). Sempre que existir o carater '.' (ponto) no select, o NEO
irá utilizar o tradutor próprio. Nós demais casos ele irá retornar o resultado do Hibernate.
O QueryBuilder constrói queries do Hibernate (HQL) então os joins e wheres são especificados da mesma forma
que o hibernate. Exemplo:
return new QueryBuilder<Aluno>(hibernateTemplate)
.from(Matricula.class)
.leftOuterJoin("matricula.aluno")
.list();
Nesse exemplo fizemos uma query from Matricula e com join em aluno. Também seria possível definir um alias
para o join:
return new QueryBuilder<Aluno>(hibernateTemplate)
.from(Matricula.class)
.leftOuterJoin("matricula.aluno aluno")
.list();
A query montada pelo exemplo acima seria "from Matricula matricula left outer join matricula.aluno aluno".
Existem outros métodos para diferentes tipos de join no QueryBuilder.
O QueryBuilder tem um suporte especial para cláusulas where. Exemplo:
public List<Aluno> findByNome(String nome){
return new QueryBuilder<Aluno>(hibernateTemplate)
.from(Aluno.class)
.where("aluno.nome = ?", nome)
.list();
}
Nesse exemplo será montada uma query da seguinte forma: "from Aluno aluno where aluno.nome = ?" e
será passado como parâmetro o campo nome. Se o nome for nulo o QueryBuilder elimina essa condição
da query: "from Aluno aluno"
É possível utilizar várias condições no mesmo queryBuilder,
o NEO manipula a query sempre que um determinado parametro for null.
É possível criar parenteses com os métodos openParentheses() e closeParentheses() e também
utilizar a cláusula or para separar as condições:
.from(NotaFiscal.class)
.leftOuterJoin("notaFiscal.cliente cliente")
.where("cliente.nome = ?", nomeCliente)
.or()
.openParentheses()
.where("notaFiscal.data < ?", data)
.where("notaFiscal.numero > ?", numero)
.closeParentheses()
.list()
Existem alguns métodos especiais no QueryBuilder para facilitar a construção de cláusulas where. Exemplo:
.whereLike("aluno.nome", nome)
Note que nos métodos especiais não deve ser colocada a interrogação '?'. Esse código equivale a escrever:
.where("aluno.nome like ?", "%" + nome + "%");
Os QueryBuilder possui métodos equivalentes as cláusulas do HQL o que facilita o entendimento.
SaveOrUpdateStrategy
Assim como existe uma classe auxiliar para executar queries, existe também uma
classe para salvar informações no banco de dados. Essa classe é a SaveOrUpdateStrategy
que também trabalha em cima do hibernate. Com ela é possível definir várias atividades a ser executadas
em determinado bean e executá-las dentro de uma transação.
Para salvar um objeto no banco de dados:
Aluno aluno = ...;
new SaveOrUpdateStrategy(hibernateTemplate, aluno)
.saveEntity()
.execute();
-
new SaveOrUpdateStrategy(hibernateTemplate, aluno)
(linha 2)
Cria um saveOrUpdateStrategy para o bean aluno.
-
.saveEntity()
(linha 3)
Adiciona uma atividade ao saveOrUpdateStrategy
para salvar o bean em questão (aluno).
-
.execute()
(linha 4)
Executa todas as atividades requeridas dentro da mesma
transação.
Com o saveOrUpdateManaged também é possível salvar coleções de dados do bean.
Veja o exemplo:
new SaveOrUpdateStrategy(hibernateTemplate, aluno)
.saveEntity()
.saveOrUpdateManaged("matriculas")
.execute();
Nesse caso, o bean aluno será salvo, assim como os itens da propriedade matriculas.
Podem ser salvas quantas coleções forem necessárias. Para isso é só chamar o
método saveOrUpdateManaged para cada propriedade. O método saveEntity deve ser chamado
apenas uma vez, e antes de salvar as coleções. Para cada coleção o SaveOrUpdateStrategy
insere os itens novos, atualiza os itens que já estavam no banco e remove do banco
os itens que não estão na lista. Esse tipo de comportamento é bastante utilizado
em telas do tipo mestre/detalhe.
As tarefas de salvar o bean e as coleções serão executadas dentro de uma transação.
TransactionTemplate
O transactionTemplate é uma classe que possibilita a utilização de transações de uma forma simples e eficiente. Sem
a necessidade de blocos try, catch, finally.
Para utilizar o transactionTemplate utilize a injeção de dependencia. Exemplo:
import org.springframework.transaction.support.TransactionTemplate;
import br.com.linkcom.neo.bean.annotation.Bean;
@Bean
public class Operador {
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void calcular(){
[bloco de código que deve estar dentro de uma transação]
}
}
Depois de configurado o bean, basta utilizar o método execute do transactionTemplate conforme o modelo:
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import br.com.linkcom.neo.bean.annotation.Bean;
@Bean
public class Operador {
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void calcular(){
transactionTemplate.execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status) {
[bloco de código que deve estar dentro de uma transação]
return null;
}}
);
}
}
O código será executado dentro de uma transação. O método execute recebe como parâmetro
um TransactionCallback que foi representado no exemplo por
uma classe anonima. A classe TransactionCallback
possui um método doInTransaction, dentro desse método deve
ser colocado o código a ser executado dentro da transação.
O método doInTransaction pode retornar algum valor se necessário
(caso contrário é só retornar null). Mais informações sobre o
TransactionTemplate podem ser encontradas na documentação do Spring.
GenericDAO
DAO é um design pattern bem simples e amplamente utilizado no desenvolvimento de aplicações.
Esse design pattern consiste em uma classe que possui todas as chamadas de acesso a banco para
determinada entidade. Todas as queries ficam dentro dos DAOs proporcionando uma melhor organização
da aplicação. Veja um exemplo de DAO:
package teste;
import java.util.List;
import org.springframework.orm.hibernate3.HibernateTemplate;
import br.com.linkcom.neo.bean.annotation.Bean;
import br.com.linkcom.neo.persistence.QueryBuilder;
import br.com.linkcom.neo.persistence.SaveOrUpdateStrategy;
@Bean
public class AlunoDAO {
HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
public void save(Aluno aluno){
new SaveOrUpdateStrategy(hibernateTemplate, aluno)
.saveEntity()
.execute();
}
public Aluno load(Integer id){
return new QueryBuilder<Aluno>(hibernateTemplate)
.from(Aluno.class)
.idEq(id)
.unique();
}
public List<Aluno> findAll(){
return new QueryBuilder<Aluno>(hibernateTemplate)
.from(Aluno.class)
.list();
}
public void delete(Aluno aluno){
hibernateTemplate.delete(aluno);
}
}
Importante: O NEO em vários lugares utiliza padrões de nomeclatura para configurar a
aplicação. Nos DAOs sempre utilize [nome do bean]DAO. Para o bean Aluno, AlunoDAO.
Para o bean Matricula, MatriculaDAO.
Esse é um DAO simples que possui os métodos save, load, findAll e delete. Sempre que a aplicação
precisar de acessar algum dado relativo a aluno é só pedir para o AlunoDAO. Como o DAO é muito
comum, o NEO possui uma implementação padrão. Para implementar o DAO do NEO basta extender
GenericDAO. Exemplo:
package teste;
import br.com.linkcom.neo.persistence.GenericDAO;
public class AlunoDAO extends GenericDAO<Aluno> {
}
Não é necessário escrever nenhum algorítmo e nem anotar a classe com @Bean.
Esse DAO vem com os métodos mais comuns implementados.
Veja um exemplo de utilização esse DAO:
package teste;
import java.util.List;
import br.com.linkcom.neo.bean.annotation.Bean;
@Bean
public class GerenciaAluno {
AlunoDAO alunoDAO;
public void setAlunoDAO(AlunoDAO alunoDAO) {
this.alunoDAO = alunoDAO;
}
public void executar(){
Aluno novoAluno = new Aluno();
novoAluno.setNome("aluno teste");
alunoDAO.saveOrUpdate(novoAluno);
List<Aluno> all = alunoDAO.findAll();
for (Aluno aluno : all) {
System.out.println(aluno.getNome());
}
}
}
O GenericDAO além dos métodos saveOrUpdate e finAll mostrados, possui métodos para deletar e carregar beans.
É possível adquirir uma referência para o HibernateTemplate, JdbcTemplate e TransactionTemplate
com os métodos getHibernateTemplate(), getJdbcTemplate(), getTransactionTemplate() respectivamente.
O GenericDAO também possui os métodos query() que cria um QueryBuilder com a cláusula from já configurada para
a classe do DAO em questão. E também possui o método save(...) que recebe um bean como parâmetro,
esse método cria um saveOrUpdateStrategy com a operação saveEntity já configurada. Veja um exemplo do
uso desses métodos:
package teste;
import java.util.List;
import br.com.linkcom.neo.persistence.GenericDAO;
public class AlunoDAO extends GenericDAO<Aluno>{
public List<Aluno> find(){
return query().list();
}
public void saveAluno(Aluno aluno){
save(aluno).execute();
}
}
Esse exemplo serve apenas para demonstrar a utilização do método save e query.
O GenericDAO também possui outros métodos que facilitam a criação de cruds e de combos.
Portanto para utilizar toda a potencialidade do NEO é recomendável criar DAOs que estendam GenericDAO.
Configurando o cache do hibernate.
O NEO traz também a possibilidade de integrar com o cache que é fornecido pelo hibernate, o cache de segundo nível e também o cache de querys.
Caso o seu data-source tenha sido configurado pelo connection.properties adicione o seguinte trecho ao arquivo applicationConfig.xml:
[JSP]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<bean name="config" class="br.com.linkcom.sined.util.config.NeoConfig" autowire="autodetect">
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
</bean>
Caso o seu datasource foi configurado manualmente pelo spring, adicione as seguintes linhas:
[JSP]
<bean id="sessionFactory" class="br.com.linkcom.neo.hibernate.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
Com isso o NEO já está preparado para suportar o cache.
Utilizando o cache para as query's
No QueryBuilder, está disponível o método useCache, que deve ser usado da seguinte maneira:
new QueryBuilder<Bean> queryBuilder = new QueryBuilder<Bean>(getHibernateTemplate());
.useCache(true)
.from(Bean.class)
.unique();
A partir desse momento, o neo repassará ao hibernate que o resultado deverá ficar em cache.