Recriar Session Factory em tempo de execução [RESOLVIDO]

fala galera…

estou com um pequeno probleminha…

eu tenho um sistema web que usa hibernate pra conectar ao banco…
no sistema é possivel escolher qual banco se quer conectar (SQL Server ou MySql), ip do servidor, porta, database, usuario e senha.
depois de escolher o banco, eu pego o hibernate.cfg.xml, mudo os parametros e salvo.

o meu problema é:
como eu faço pra recriar o sesion factory usando o novo hibernate.cfg.xml criado em tempo de execução?

eu preciso fazer o session factory reconhecer o arquivo hibernate.cfg.xml novo e criar um mapeamento com o novo banco, mas nao estou conseguindo.
eu consigo recriar o sesion factory, mas ele ainda pega as configurações do arquivo hibernate.cfg.xml antigo. pra fazer reconhecer o novo eu tenho que parar o tomcat.

eu gostaria de saber se alguem sabe uma forma de nao precisar reiniciar o tomcat para usar essas configurações novas do hibernate.cfg.xml.

meu HibernateUtil

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from (hibernate.cfg.xml) config file.
            sessionFactory = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();

        } catch (Throwable ex) {
            // Log the exception. 
            System.err.println("Initial SessionFactory creation failed." + ex);
            ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void resetSessionFactory() {

        try {
            // mata o sesion factory.
            sessionFactory.close();
            sessionFactory = null;
            // recria o session factory.
            sessionFactory = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();

        } catch (Throwable ex) {
            // Log the exception.
            System.err.println("Initial SessionFactory creation failed." + ex);
            ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
        }
    }
}

eu uso o método resetSessionFactory para recriar o session factory, mas nao reconhece as configurações novas.

ps: nao me agrada mto a ideia de usar dois hibernate.cfg.xml.

[]´s

se não é estatico, não use o hibernate.cfg.xml … simplismente sete manualmente as prorpiedades…

new AnnotationConfiguration().setProperty(key,value).setProperty(key2,value2)…configure().buildSessionFactory();

desculpe a demora…eu estava totalmente enrolado…

  • obrigado Lavieri funcionou a sua sugestao…
    mas tive que mudar a forma como eu configurava o hibernate, agora to usando o properties, mas isso nao é um problema…

vlw mesmo!!!

E ae Mathias85,

Você poderia mandar o exemplo de como ficou a implementação, pois estou precisando fazer algo parecido.

Valeu!!!

[]'s

arsinfo Desculpa a demora pra responder…carnaval…empresa mudando de lugar…mow confusao…

a forma como eu fiz foi usando properties mesmo…
ai vai o codigo do meu HibernateUtil
to usando hibernate annotation

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {
        try {
            // abre o properties com as configurações do hibernate (conexão e propriedades)
            Properties propriedades = new Properties();
            propriedades.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("merx.properties"));

            // chama o méto que cria o session factory usando o properties.
            createSessionFactory(propriedades);

        } catch (Throwable ex) {
            // Log the exception. 
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    /**
     * Método que (re)cria o SessionFactory a partir de um arquivo properties passado.
     * 
     * @param propriedades
     */
    public static void createSessionFactory(Properties propriedades) {

        try {

            AnnotationConfiguration cfg = new AnnotationConfiguration();
            // seta as configurações do properties passado no cfg do hibernate.
            cfg.setProperties(propriedades);

            // define configurações adicionais do hibernate (pode ser colocado no properties tambem)
            cfg.setProperty("hibernate.show_sql", "true")
                    .setProperty("hibernate.format_sql", "true")
                    .setProperty("hibernate.hbm2ddl.auto", "update")
                    .setProperty("hibernate.transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory")
                    .setProperty("hibernate.current_session_context_class", "thread");

            // pacotes onde estao as classes que serao adicionadas como Entitys no hibernate
            String[] pacotes = {"ModuloAdministracao.Dtos", "ModuloContas.Dtos"};
            // chama o metoto que varre os pacotes buscando as classes
            List<Class> listaClasses = getClasses(pacotes);
            // adiciona as classes como Entitys no hibernate
            for (Class classe : listaClasses) {
                cfg.addAnnotatedClass(classe);
            }
            
            // (re)constroi o SessionFactory
            sessionFactory = cfg.buildSessionFactory();
        } catch (Throwable ex) {
            // Log the exception.
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    /**
     * Método que varre o pacote e retora a lista com todas as classes que estao
     * dentro desse pacote.
     * 
     * @param pacotes um array de strings com os nomes completos dos pacotes
     * @return 
     * @throws ClassNotFoundException
     */
    private static List<Class> getClasses(String[] pacotes) throws ClassNotFoundException {

        List<Class> listaClasses = new ArrayList<Class>();
        for (String nomePacote : pacotes) {
            String caminho = '/' + nomePacote.replace('.', '/');
            URL url = Thread.currentThread().getContextClassLoader().getResource(caminho);
            if (url != null) {
                File diretorio = new File(url.getFile());
                if (diretorio.exists()) {
                    String[] arquivos = diretorio.list();
                    for (String arquivo : arquivos) {
                        if (arquivo.endsWith(".class")) {
                            String nomeClasse = arquivo.replace(".class", "");
                            listaClasses.add(Class.forName(nomePacote + '.' + nomeClasse));
                        }
                    }
                }
            }
        }
        return listaClasses;
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

aqui vai o arquivo properties

# Propriedades de conexão com o banco de dados
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.connection.driver_class=com.microsoft.sqlserver.jdbc.SQLServerDriver
hibernate.connection.url=jdbc:sqlserver://locahost:1433;databaseName=NomeDoBancoDeDados
hibernate.connection.username=user
hibernate.connection.password=********

o que voce tem que fazer eh reescrever esse properties e chamar o metodo HibernateUtil.createSessionFactory(seuArquivoPropertiesModificado)

qualquer duvida ou sugestao estamos ai…

[]´s

Valeu!!!