Вернуть диалект из SessionFactoryBuilder - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть класс SessionFactoryBuilder. Этот класс создает сеанс и возвращает его, но я здесь использую аннотации, и это делается только во время запуска сервера. В качестве файла конфигурации базы данных я использую hibernate.cfg.xml, в середине - информация для oracle или postgresql. Поэтому я должен различать, какие данные в данный момент находятся в файле. Я думал сделать это, скачав диалект, но у меня проблемы сами.

import repository.database.DatabaseSettings;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.dialect.Database;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.inject.Produces;
import javax.inject.Singleton;

@Singleton
public class SessionFactoryBuilder {

    private SessionFactory sessionFactory;
    private static Dialect dialect;

    @PostConstruct
    void buildSessionFactory(){
        final StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
        try{
            Metadata metadata = new MetadataSources(standardServiceRegistry).buildMetadata();
            sessionFactory = metadata.buildSessionFactory();
            dialect = metadata.getDatabase().getDialect();
        }catch(Exception e){ 
            StandardServiceRegistryBuilder.destroy(standardServiceRegistry);
            e.printStackTrace();
            throw new ExceptionInInitializerError(e);
        }
    }

    @Produces
    public SessionFactory getSessionFactory(){
        return sessionFactory;
    }

    @PreDestroy
    void destroySessionFactory(){
        sessionFactory.close();
    }
}


import org.hibernate.Session;
import org.hibernate.SessionFactory;

import javax.annotation.PreDestroy;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

@RequestScoped
public class MySessionFactory implements SessionFactoryTemplate {

    @Inject
    private SessionFactory sessionFactory;

    private Session currentSession;

    @Override
    public Session getCurrentSession() {
        if(currentSession == null) {
            currentSession = sessionFactory.openSession();
        }
        return currentSession;
    }

    @PreDestroy
    private void closeSession(){
        if(currentSession != null && currentSession.isOpen()){
            currentSession.close();
        }

    }
}

Я думал, что если я создам статическое поле, оно будет работать в другом классе dialect = SessionFactoryBuilder.dialect, но это nullPointerException. У меня есть класс ресурсов, в котором @Inject MySessionFactory sessionFactory; и желательно, чтобы я использовал этот диалект, если он признает, что это диалект Oracle, который запрашивает запросы к базе данных Oracle и т. д. К сожалению, я не хотел бы слишком сильно изменять классы MySessionFactory и SessionFactoryBuilder, поскольку это зависит от приложения и является синонимом. с большими изменениями. Есть ли возможность вернуть этот диалект? Я знаю, что void buildSessionFactory () вызывается только тогда, когда я запускаю wildfly, поэтому этот нуль и то, что я прочитал, аннотацию @Produces, которая возвращает что-то, можно использовать один раз, поэтому я не вижу выхода, но, возможно, один из вас ? Пожалуйста, помогите.

...