O hibernate trabalha com dois bancos de dados diferentes, um local e outro servidor. Ambos bancos apresentam a mesma estrutura de tabelas, porém são bancos com tecnologias diferentes.
Eu tenho uma entidade que se relaciona com outra entidade em uma relação 1-N
Entidade A pode ter N entidades B.
ETA1 - ETB1
ETA1 - ETB2
ETA1 - ETB3
ETA1 contém 3 ETBs.
O problema que leio a entidade A de uma EntityManager que está associada ao banco 1, e desejo copiar o valor dessa entidade (inclusive todo seu relacionamento) para o banco 2 (que está associado com outro EntityManager)
Quando gravo os dados de uma base para outra, o relacionamento no banco 2 é perdido, simplesmente ele copia todos os dados e todo o seu relacionamento, porém a coluna na entidade B que guarda o valor da chave primária da entidade relacionada em A não é guardado.
Então eu gostaria de saber qual a melhor maneira para copiar, transferir objetos entre EntityManagers diferentes, sessões diferentes, seria usando Interceptores em Hibernate?
Quando vc realiza um load(), ele é lazy-loading, será carregado a partir do momento que vc utiliza o objeto, entao se vc carrega um objeto e passa para outro banco e em momento algum vc o carregou, terá probelmas, tente carregar o objeto com o metodo get();
Quando vc realiza um load(), ele é lazy-loading, será carregado a partir do momento que vc utiliza o objeto, entao se vc carrega um objeto e passa para outro banco e em momento algum vc o carregou, terá probelmas, tente carregar o objeto com o metodo get();[/quote]
Eu entendi, mas mesmo assim eu continuo tendo problemas.
Eu tinha buscado o objeto da lista que carreguei de um gerenciador de entidades.
Depois eu simplesmente criei um objeto e o associe ao objeto trazido da outra EM.
Porém depois eu preenchi na mão criando um objeto e pegando todos os atributos de um e passando para o outro, e quando fui persistir na otura base que seria a base da exportação o objeto persistiu usando merge, porém a coluna de relaciona não foi preenchida e não sei pq.
passa pra o outro contexo e verifique o estado dele, com certeza será transient;
vc está executando o merge() tudo certinho com o comit() e tal ?[/quote]
As duas entidades de teste que estou usando são:
Auditoria e Procedimento.
Auditoria pode ter N procedimentos. Veja a parte do código que joga elas do banco A para o banco B.
public void download(Class pEntity) throws Exception {
Query lQuery = emRemote.createQuery("SELECT m FROM " + pEntity.getName() + " m");
List<Auditoria> lista = lQuery.getResultList();
if (lista != null && lista.size() > 0) {
for (Auditoria lA : lista) {
//popula uma nova auditoria com seus procedimentos
Auditoria lModel = new Auditoria();
lModel.setDescricao(lA.getDescricao());
lModel.setId(lA.getId());
lModel.setVersaoOnline(lA.getVersaoOnline());
lModel.setVersaoOffline(lA.getVersaoOffline());
lModel.setProcedimentos(new ArrayList<Procedimento>());
lModel.setSituacao(0);
for (Procedimento p : lA.getProcedimentos()) {
Procedimento lProc = new Procedimento();
lProc.setId(p.getId());
lProc.setDescricao(p.getDescricao());
lProc.setVersaoOffline(p.getVersaoOffline());
lProc.setVersaoOnline(p.getVersaoOnline());
lProc.setSituacao(0);
lModel.getProcedimentos().add(lProc);
}
//lModel = lA;
emLocal.merge(lModel);
}
emLocal.getTransaction().commit();
//baixar registro de Identificador incrementado + 1
Identificador lIden = emRemote.find(Identificador.class, new Long(1l));
lIden.setEstacao(incrementarEstacao(lIden.getEstacao()));
//verifica se já existe no banco local, caso não exista, será comitada tanto
//em local quanto em remoto.
Identificador localIden = emLocal.find(Identificador.class, new Long(1l));
if (localIden == null) {
persist(lIden, 0);
persist(lIden, 1);
}
}
}
Código do persist
/**
* 0 - local
* 1 - remoto
* @param pModo
* @param pModel
*/
public void persist(GenericModel pModel, int pModo) {
if (pModo == 0) {
getEntityManager(0);
emLocal.merge(pModel);
emLocal.getTransaction().commit();
} else {
getEntityManager(1);
emRemote.merge(pModel);
emRemote.getTransaction().commit();
}
}
Grivon, só para te adiantar, quando vc usa este esquema de ejb e hibernate com 2 contexto persistentes deve evitar o “Open Session in view”, por causa disso que está aconteçendo com vc
Acho que o problema que este objeto que vc está inserido, não pertence ao contexo, entende !!
vc não consegue carregar um objeto no ContextoPesistenteA usando o get() e
no ContextoPesistenteB criar outro objeto que esteja setado tbm no seu arquivo de configuração, ou melhor que esteja @Entity
e settar este objetos com os parametros do objeto passado no ContextoPersistenteA ?
dá um sysout, vê se os atributos foram carregados no contexoB
Como pode-se perceber, o hibernate cria a coluna PRC_ADT_ID na tabela de Procedimento, essa coluna irá armazenar o ID da Auditoria.
Esse é o dado que não está sendo levado, e como simplesmente eu não posso setá-lo na mão então quando passo a Auditoria com os procedimentos relacionados do banco A para o banco B os valores para a coluna PRC_ADT_ID ficam todos nulos.
Vc está conseguindo carregar e enviar o objeto, mas tenta criar um objeto para o seu relacionamento tbm, e passar estes 2 objetos carregados atravez do metodo get();
faz esse teste por ai…
Se vc não tivesse usando anotações de Cascating deveria executar um save(), no objeto e outro save() em seus relacionamentos, acho que pode ser isso, carrege os dois, de um new para o objeto carrageado do relacionamento…
Com certeza o relacionamento está gerenciado no contextoA e o contextoB não consegue captura-los, tenta na mão mesmo, carregue o relacionamento e tranfira para outro objeto, e repa-se para o contexto B