Erro deploy entities

Olá pessoal,

Novamente volto com o problema de deploy de entities.

Bom, eu fiz o seguinte teste. Um projeto EAR que possui apenas uma entity (usuario) e que possui a seguinte estrutura:

app1.ear

/META-INF/application.xml app1-entity.jar (tem apenas a entity Usuario.java e o persistence.xml, apontado para o ds app1) app1-service-impl.jar (contendo @Local UsuarioFacadeLocal, @Remote UsuarioFacadeRemote e @Stateless UsuarioFacadeBean) app1-service.jar (contendo UsuarioFacade) app1-web.war

O próximo EAR precisa da entity Usuario. Portanto, distribuí o jar app1-entity.jar e app1-service.jar no app2. Segue a estrutura:

app2.ear

/lib/app1-entity.jar /lib/app1-service.jar /META-INF/application.xml app2-entity.jar (tem apenas a entity Log.java e o persistence.xml, apontando para o ds app2. Log possui uma referência ManyToOne para Usuario) app2-service-impl.jar (contento @Local LogFacadeLocal, @Remote LogFacadeRemote e @Stateless LogFacadeBean) app2-service.jar (contendo LogFacade) app2-web.war

Quando faço o deploy dessas duas aplicações, não ocorre nenhum erro. Porém, existem duas instâncias da classe Usuario (uma que subiu em app1 e outra que subiu em app2). Li num site wiki do jboss que esse tipo de coisa pode gerar ClassCastException (o que já ocorreu em um outro projeto - por isso estou fazendo esse teste). http://wiki.jboss.org/wiki/Wiki.jsp?page=ClassCastExceptions.
Para tentar resolver esse problema, eu tirei o app1-entity.jar do app2.ear. Porém, ele não consegue fazer deploy, Segue o erro:

09:24:32,143 WARN  [ServiceController] Problem starting service persistence.units:ear=app2.ear,unitName=managerApp2
org.hibernate.AnnotationException: @OneToOne or @ManyToOne on br.unicamp.hc.app2.ejb.entity.Log.usuario references an unknown entity: br.unicamp.hc.app1.ejb.entity.Usuario

Agora estou com esse problema. Se duplico os jars, corro o risco de ter uma ClassCastException. Se não duplico, uma aplicação não acha o jar da outra.

Como posso resolver esse problema?

Obrigada!

ola,
não existe a necessidade de vc duplicar arquivos EAR/JAR que contem ejbs.
Quando vc faz um deploy de um ejb(tanto faz se estiver em um EAR ou JAR) o container vai disponibilizar isso como se fossem “serviços”, registrando eles na arvore JNDI. Com isso vc pode acessa-los fazenso lookup usando JNDI.
Provavelmete na hora de acessar esses EJB’s vc esta errando algum detalhe, por isso não estão sendo encontrados.

[]´s

Olá jgbt,

É, eu percebi que ele disponibiliza os ejbs como serviços. Tanto que no app2.ear eu faço um lookup para um facade do app1, mesmo sem ter o app1-service-impl.jar no projeto.

O problema são as entidades :frowning:

Se duplicar o jar que tem apenas as entidades, várias instâncias são criadas, podendo gerar o erro de classcastexception. Se não duplicar, não faz deploy do app2-entity.jar pois esse depende de uma entity que está em app1-entity.jar, que estará apenas em app1.ear.

Como posso solucionar esse problema? Pensei em usar interfaces para as entities, do mesmo jeito que faço com os facades, mas acho que não vai funcionar…

[]s

ola,
vc esta usando EJB2 ou EJB3?

Se vc estiver usando EJB3, os Entitys não podem ser acessados remotamentes, ou seja, vc não vai ter acesso a um Entity Bean via JNDI de outro projeto. A especificação não permite mais.
Vc tem que criar facades(Sessions Beans) para fazer acesso ao Entitys.

[]´s

Oi,

Estou usando EJB3. Mas não estou tentando acessar remotamente. Estou tentando acessar como parte de um mapeamento.

Imagine que app1.ear cuida de dados do usuário (páginas, serviços, etc). Lá, eu deixaria mapeado a entity Usuario. Já em app2.ear, eu teria dados de outro sistema. Porém, eu preciso relacionar também com o Usuário. Nesse caso, eu teria a entity Usuario no app1.ear e Log no app2.ear, que usa Usuario num mapeamendo ManyToOne.

app1-entity.jar

package br.unicamp.hc.app1.ejb.entity; //imports @Entity @Table(name = "usuario") @SequenceGenerator(sequenceName = "usuario_id_usuario_seq", name = "seq_usuario") public class Usuario implements Serializable { private static final long serialVersionUID = -482165038700693347L; private int id; private String nome; private String login; ///get e set }

app2-entity.jar

package br.unicamp.hc.app2.ejb.entity; //imports import br.unicamp.hc.app1.ejb.entity.Usuario; @Entity @Table(name = "log") @SequenceGenerator(name = "seq_log", sequenceName = "log_id_log_seq") public class Log implements Serializable { private static final long serialVersionUID = -6158386139765588301L; private int id; private Date date; private String descricao; private Usuario usuario; //gets e sets @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "id_usuario") public Usuario getUsuario() { return usuario; } }

Estou pensando nesse tipo de integração de vários sistemas (ears).
Queria deixar as entity mapeadas apenas nos seus respectivos sistemas, que englobam uma área de negócio. Mas na base, essas áreas estarão interligadas. Por isso preciso dos mapeamentos.

Eu sei que fazendo isso eu não conseguirei independencia total dos sistemas, já que a base está bem acoplada (ainda que usando schemas diferentes). Só não queria classes duplicadas (que, pelo que li e testei, dá erro ao ter mais de uma instância no servidor).

O que faço? :frowning:

[]s

Humm… se eu entendi, vc não vai conseguir fazer o que vc quer.
Algumas coisas:

  • vc pode ter cada area como um jar, e agrupar eles em um EAR. não tem necessidade de ter varios EAR’s.
  • vc quer isolar areas de negocio? mas se User precisa/usa Log, eles fazem parte do mesmo negocio, ou mesmo dominio. Não vejo sentido em separ-los.
  • acho que vc pode ter um componete/sistema que manipula isso. se outro sistema precisar usa-los, vc busca eles no primeiro sistema e trafega a entidade ja com o reacionamento carregado.

[]´s

Eu estava com medo de ler isso :smiley:

Bom. Eu concordo que se um precisa/usa de outro, logo eles não são tão independentes :smiley:

Mas a idéia de fazer esses ears separados é porque trabalho num hospital, onde cada área tem um sistema, que juntos formam o sistema de gestão hospitalar. Minha idéia seria ter um enfermaria.ear, obito.ear, agendamento.ear, prontuario.ear, e por aí vai. Sei que são vários sistemas que, pela base, estão relacionados de alguma maneira. Por exemplo, o paciente com certeza está relacionado com todos os sistemas.

Não queria ter um ear de sistema hospitalar com os módulos dentro para não ficar amarrada nisso. Imagino que os sistemas serão feitos um por um. Se eu os tivesse em cada ear, cada vez que um entrasse em produção, eu precisaria apenas adicionar o ear no jboss e boa :D.Porém, se eu tiver tudo num ear só, eu teria que recompilar td de novo para fazer o deploy.

Por isso tive a idéia de distribuir a interface dos serviços com as entidades. Assim, eu conseguiria mapear.

Talvez se eu conseguisse isolar as entidades das regras de negócio, eu conseguisse manter cada ear por sistema e um ear com as entidades…
Fica muito amador? :smiley:

[]s

Ola,
Sim, não tem necessidade de vc ter entitys que no fim mapeiam a mesma base espalhados pelos modulos.
Acho que no seu caso, vc poderia ter um servico/componente que manipulasse as entidades via facade. Centralizando em um unico lugar e independente de modulo de negocio.
Todos os outros modulos usariam esse modulo quando precisassem ler/manipular os entitys.

[]´s