Olá Daniel e Rita
Essa confusão que surgiu sobre o funcionamento do merge
é por causa da spec da JPA.
If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X'
of the same identity or a new managed copy X' of X is created.
Então quando executamos o código:
public class TestaMergeUpdateCascade {
public static void main(String[] args) {
JPAUtil factory = new JPAUtil();
EntityManager manager = factory.getEntityManager();
//Entity Detached
Conta conta = new Conta();
conta.setTitular("Rita Lima");
conta.setNumero("01010");
conta.setAgencia("1011");
conta.setBanco("033 - BANCO SANTANDER");
conta.setId(12);
manager.getTransaction().begin();
Conta contaManaged = manager.merge(conta);
for (Movimentacao movimentacao : contaManaged.getMovimentacoes()) {
System.out.println("Movimentacao " + movimentacao.getId() + " - " + movimentacao.getDescricao());
}
manager.getTransaction().commit();
manager.close();
factory.close();
}
}
A variável contaManaged
realmente está no estado managed da JPA, porém como é dito no texto da spec, essa entidade managed possui o estado copiado da entidade transient com id que foi passado como argumento para o merge. Então como a lista de movimentações da variável conta
ainda não foi inicializada (está null
), a entidade managed devolvida pelo merge também terá a lista de movimentações nula.
Sobre a Jpql vs Criteria, a pergunta do Daniel, essas duas apis são ferramentas feitas para resolver problemas específicos da aplicação. Quando queremos executar sempre a mesma query no banco de dados, é melhor utilizar a JPQL (ou HQL), pois o código com a criteria é mais complicado. Já no caso em que temos que implementar uma query mais dinâmica, é melhor utilizar a criteria.