Hibernate com mapeamentos em diferentes projetos

9 respostas
adrianostanley

Pessoal, to com um problema sério com relação ao mapeamento de classes do hibernate.

Para minha aplicação geral, faço uso de 4 projetos. Um deles, o Core, contém todas as classes de domínio do sistema. Após uma demanda, precisamos criar um outro projeto separado que faz uso do Core (inclusive das classes de domínio) porém com novas classes de domínio que atenderão somente às necessidades desse pacote e que não podem ir para o Core.

O Core tem um hibernate.cfg.xml contendo as classes a serem inicializadas. Antigamente todas as classes de domínio eram do Core, então não havia problemas. Mas com essas novas classes de domínio no outro projeto não posso referenciá-las no xml pois o Core não faz referência à esse pacote por causar dependência cíclica.

Minha dúvida é, há como adicionar classes a serem mapeadas além do .xml? Pensei em criar uma forma de adicionar essas classes para entrarem no conjunto de classes do Hibernate somente para as aplicações que farão uso desse novo projeto.

Desde já agradeço pela atenção! Se tiver ficado confuso tento explicar de outra forma. =)

Atenciosamente,
Adriano Castro

9 Respostas

R

A classe Configuration do Hibernate permite incluir mapeamentos de classes via programação:

http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/cfg/Configuration.html
http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/cfg/Configuration.html#addFile(java.io.File)

Além do método addFile(), há vários outros que lhe permitem incluir mapeamentos à parte.

adrianostanley

Mas é possível manter o cfg.xml e adicionar outras classes posteriormente via código ou preciso migrar tudo pra código?

R

Pode manter o cfg.xml e adicionar depois o que precisar, não precisa fazer tudo via programação.

adrianostanley

Infelizmente não funcionou.

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    private static final AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration();

    static {
        try {
            sessionFactory = annotationConfiguration.configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static void addClass(Class clazz) {
        sessionFactory = annotationConfiguration
                .addAnnotatedClass(clazz)
                .configure()
                .buildSessionFactory();
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static Session openSession() {
        return sessionFactory.openSession();
    }
}

Deixei desta forma e ele reclama dizendo que estou duplicando os mapeamentos. Detalhe, chamo o addClass em um bloco static do primeiro DAO do meu projeto a parte.

R

Uma maneira (trabalhosa) de conseguir o resultado desejado é NÃO incluir mapeamentos no cfg.xml, e em seguida incluir cada mapeamento de que precisar via addClass(). Para economizar programação, você poderia criar um método estático para incluir os mapeamentos básicos numa instância de Configuration, e chamar esse método em todos os projetos subjacentes.

adrianostanley

Eu até pensei nisso e criei um método público estático dentro do meu HibernateUtil como visto acima que adiciona uma classe.

O problema é que quando eu adiciono uma classe, ele reclama dizendo que há classes duplicadas, como se ele tentasse recarregar tudo que já tem + o que eu solicitei.

public static void addClass(Class clazz) { sessionFactory = annotationConfiguration .addAnnotatedClass(clazz) .configure() .buildSessionFactory(); }

Se eu tiro o .configure() ele não reclama que há classes duplicadas mas também não reconhece a entidade quando um DAO a solicita.

R

Seu objeto Configuration certamente abarca um bocado de classes automaticamente por causa das anotações (via AnnotationConfiguration). Se você usar Configuration, sem ler classes anotadas, acho que conseguirá o efeito desejado.

adrianostanley

Deve ser por isso que ele marca AnnotationConfiguration como deprecated. Mais tarde tentarei e retorno com ou sem sucesso. Obrigado!

adrianostanley

Não dá também. Ele reclama porque uma das minhas classes que estão no pacote orignal tem uma lista de objetos que uma dessas classes do novo pacote também têm. E aí ele tenta mapear essa lista duas vezes! Acho que não há como mesmo fazer esse mapeamento meio que em tempo de execução não.

Criado 16 de agosto de 2011
Ultima resposta 17 de ago. de 2011
Respostas 9
Participantes 2