Fórum JPA não atualizar entidade automaticamente #510216
10/02/2015
0
Criei o tópico na sessão de JPA pois pesquisando pela internet, creio que seja algo relacionado a configuração de Cache do hibernate porém ainda não consegui encontrar a solução, caso alguém ja tenha passo por isso ou tenha alguma luz sobre o assunto me avise por favor.
Obrigado, até mais
Obs: já tive o mesmo problema, até citado em tópicos anteriores, na ocasião acabei resolvendo utilizando a configuração <shared-cache-mode>none<shared-cache-mode> no meu arquivo persistence.xml... Não sei se foi a melhor solução mas na epoca resolveu. Acontece que agora estou utilizando Spring nessa aplicação e não disponho do arquivo persistence.xml.
Bruno Santana
Curtir tópico
+ 0Posts
10/02/2015
Ronaldo Lanhellas
Estes beans que estão no PersistenceContext ficam lá até que um comando de flush() seja dado para que o sincronismo com o banco seja feito. Quando esse "flush" é executado então os beans desta área de memória são realmente persistidos no banco.
O seu problema é que esse flush() ocorre de forma tardia, mas porque ?
- O flush pode ocorrer de várias formas mas vou citar 2:
1 - Quando você executa alguma consulta no banco de dados, ele faz o flush() dos objetos em memória;
2- VocÊ mesmo pode forçar o flush(), chamando-o explicitamente;
Minha dica, leia o material sobre PersistenceContext: https://www.devmedia.com.br/entendendo-o-java-persistencecontext-extended-e-transient/30493
Gostei + 0
11/02/2015
Bruno Santana
@Transactional(propagation=Propagation.SUPPORTS)
public abstract class DaoGenerico<T> implements DaoInterface<T> {
@Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {return sessionFactory;}
public void setSessionFactory(SessionFactory sf) {sessionFactory = sf;}
protected Session getSession() {
return getSessionFactory().getCurrentSession();
}
@SuppressWarnings("rawtypes")
protected abstract Class getClazz();
public void adicionar(T objeto) {
getSession().saveOrUpdate(objeto);
getSession().flush();
}Gostei + 0
11/02/2015
Ronaldo Lanhellas
Gostei + 0
11/02/2015
Ronaldo Lanhellas
Gostei + 0
11/02/2015
Bruno Santana
E ela está atualizada logo após o adicionar, mesmo sem utilizar o flush() :S porém quando vou acessar outra página que puxa essa lista a mesma não está completa, o objeto recém adicionado não aparece, seja em algum componente tipo o autocomplete, datatable etc do primefaces...
Será que isso é algum problema fora do "escopo JPA" ?
Gostei + 0
12/02/2015
Bruno Santana
em teoria toda vez que o bean é criado ele executa o @PostConstruct certo? meu bean está como @ViewScoped, então toda vez que faço uma navegação pra uma página que utiliza ele, ele é criado e assim popula as listas, estou enganado ? pois nao é esse o comportamento que acontece, consegui resolver o problema populando a lista fora do @postconstruct ao chamar o método do autocomplete...
veja abaixo
@Named
@ViewScoped
public class MatriculaBean {
@Autowired
private ServicoModalidade servicoModalidade;
@Autowired
private ServicoPerfil servicoPerfil;
private List<Modalidade> modalidadesDisponiveis;
private List<Modalidade> modalidadesSelecionadas = new ArrayList<Modalidade>();
@PostConstruct
private void init(){
modalidadesDisponiveis = servicoModalidade.listarEager();
alunosDisponiveis = servicoPerfil.listar();
}
public List<Modalidade> completeModalidade(String busca) {
modalidadesDisponiveis = servicoModalidade.listarEager();
List<Modalidade> filtrados = new ArrayList<Modalidade>();
if(modalidadesSelecionadas == null){modalidadesSelecionadas = new ArrayList<Modalidade>();}
for (Modalidade mod : modalidadesDisponiveis) {
if (mod.getNome().contains(busca) && !modalidadesSelecionadas.contains(mod)) {
filtrados.add(mod);
}
}
return filtrados;
}
como pode ver, tive que popular novamente a lista em meu método completeModalidade... o problema foi resolvido, agora entidades recém adicionadas a partir de uma tela de cadastro aparecem no auto-complete, mas aí fica uma dúvida, estou fazendo algo errado? Qual a melhora maneira de popular lists em um bean.. Pois por exemplo, em alguma outra página posso ter um dataTable que use uma lista populada da mesma forma, como eu faria já que não teria um método "complete" para chamar a mesma
Gostei + 0
12/02/2015
Ronaldo Lanhellas
em teoria toda vez que o bean é criado ele executa o @PostConstruct certo? meu bean está como @ViewScoped, então toda vez que faço uma navegação pra uma página que utiliza ele, ele é criado e assim popula as listas, estou enganado ? pois nao é esse o comportamento que acontece, consegui resolver o problema populando a lista fora do @postconstruct ao chamar o método do autocomplete...
veja abaixo
@Named
@ViewScoped
public class MatriculaBean {
@Autowired
private ServicoModalidade servicoModalidade;
@Autowired
private ServicoPerfil servicoPerfil;
private List<Modalidade> modalidadesDisponiveis;
private List<Modalidade> modalidadesSelecionadas = new ArrayList<Modalidade>();
@PostConstruct
private void init(){
modalidadesDisponiveis = servicoModalidade.listarEager();
alunosDisponiveis = servicoPerfil.listar();
}
public List<Modalidade> completeModalidade(String busca) {
modalidadesDisponiveis = servicoModalidade.listarEager();
List<Modalidade> filtrados = new ArrayList<Modalidade>();
if(modalidadesSelecionadas == null){modalidadesSelecionadas = new ArrayList<Modalidade>();}
for (Modalidade mod : modalidadesDisponiveis) {
if (mod.getNome().contains(busca) && !modalidadesSelecionadas.contains(mod)) {
filtrados.add(mod);
}
}
return filtrados;
}
como pode ver, tive que popular novamente a lista em meu método completeModalidade... o problema foi resolvido, agora entidades recém adicionadas a partir de uma tela de cadastro aparecem no auto-complete, mas aí fica uma dúvida, estou fazendo algo errado? Qual a melhora maneira de popular lists em um bean.. Pois por exemplo, em alguma outra página posso ter um dataTable que use uma lista populada da mesma forma, como eu faria já que não teria um método "complete" para chamar a mesma
Seu racíocinio sobre o @PostConstruct está correto, ele é chamado (no caso do ViewScoped) toda vez que você acessa a página novamente. A sua solução é um "workaround" ao problema e não é uma boa prática, o correto mesmo é popular apenas 1 vez como você estava fazendo.
Vamos analisar seu problema: Pelo que entendi a variável 'modalidadesSelecionadas' é populada normalmente no @PostConstruct mas como você adicionou um novo item este ainda não aparece na variável 'modalidadesSelecionadas', sendo assim você precisa repopular através do método completeModalidade() que trás o novo item do banco de dados. Vejamos as possibilidades:
1 - O seu @PostConstruct está sendo chamado apenas 1 vez. Depois que você adiciona o novo item e tentar ver a lista o @PostConstruct já foi chamado e por isso o novo item não aparece. Se for isso você terá que checar se o ManagedBean que você está usando está de fato sendo "recarregado", caso contrário pode tentar mudar o escopo para @RequestedScope
Gostei + 0
12/02/2015
Bruno Santana
Tive que alterar minhas anotações de escopo para @Scope... o problema agora é a limitação dessas anotações do Spring que não possuem a opção view... mas isso é outro problema...
créditos para Victor Kendy Harada que desevendou esse mistério em um outro forum
Valeu ai !!!
Gostei + 0
12/02/2015
Ronaldo Lanhellas
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)