web-dev-qa-db-ja.com

Hibernate SessionFactoryを作成しているときにDatasourceを設定するにはどうすればよいですか?

SessionFactoryを作成していて、SessionSourceを作成しているコードのオブジェクトとしてデータソースを持っていますが、データソースをHibernate構成オブジェクトに設定できません。では、どうすればデータソースをSessionFactoryに設定できますか?

Configuration configuration = new Configuration();
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
configuration.setProperties(properties);
configuration.setProperty("packagesToScan", "com.my.app");
SessionFactory sessionFactory = configuration.configure().buildSessionFactory();
20
newbie

セッションへのJDBC接続を提供するには、 ConnectionProvider の実装が必要です。

デフォルトでは、HibernateはJNDIからDatasourceConnectionProviderインスタンスを取得するDataSourceを使用します。

カスタムDataSourceインスタンスを使用するには、InjectedDataSourceConnectionProviderを使用して、DataSourceインスタンスをそのインスタンスに挿入します。

InjectedDataSourceConnectionProvider に関するTODOのメモがあります

注:setDataSource(javax.sql.DataSource)は、configure(Java.util.Properties)の前に呼び出す必要があります。

TODO:setDataSourceが実際に呼び出される場所が見つかりませんでした。これを単に設定するために渡すことはできませんか???

注記に従って、setDataSource()メソッドからconfigure()メソッドを呼び出します。

public class CustomConnectionProvider extends InjectedDataSourceConnectionProvider {
    @Override
    public void configure(Properties props) throws HibernateException {
        org.Apache.commons.dbcp.BasicDataSource dataSource = new BasicDataSource();
        org.Apache.commons.beanutils.BeanUtils.populate( dataSource, props );
        setDataSource(dataSource);

        super.configure(props);
    }
}

serSuppliedConnectionProvider を拡張することもできます。

ConnectionProviderの契約による

実装者は、デフォルトのパブリックコンストラクタを提供する必要があります。

カスタムConnectionProviderがConfigurationインスタンスを通じて設定されている場合、Hibernateはこのコンストラクターを呼び出します。

Configuration cfg = new Configuration();
Properties props = new Properties();
props.put( Environment.CONNECTION_PROVIDER, InjectedDataSourceConnectionProvider.class.getName() );
cfg.addProperties(props);
15
dira

DataSourceがJNDIに保存されている場合は、次のように使用します。

configuration.setProperty(
    "hibernate.connection.datasource",
    "Java:comp/env/jdbc/yourDataSource");

しかし、Apache DBCPやBoneCPのようなカスタムデータソースプロバイダーを使用していてSpringのような依存性注入フレームワークを使用したくない場合なら、前にStandardServiceRegistryBuilderに注入できますSessionFactoryの作成:

//retrieve your DataSource
DataSource dataSource = ...;
Configuration configuration = new Configuration()
    .configure();
//create the SessionFactory from configuration
SessionFactory sf = configuration
    .buildSessionFactory(
        new StandardServiceRegistryBuilder()
            .applySettings(configuration.getProperties())
            //here you apply the custom dataSource
            .applySetting(Environment.DATASOURCE, dataSource)
            .build());

このアプローチを使用する場合は、hibernate.cfg.xmlに接続パラメーターを配置する必要はありません。上記のアプローチを使用する場合の互換性のあるhibernate.cfg.xmlファイルの例を次に示します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
        <property name="show_sql">false</property>
        <!-- your mappings to classes go here -->
    </session-factory>
</hibernate-configuration>

上記のコードはHibernate 4.3でテストされています。

12
Luiggi Mendoza

Luiggi Mendozaの答えは、私の検索がここに送られる理由ですが、これを行う方法を探すのにかなりの時間を費やしたので、自分のバージョンを指定する必要があると思います。これは、テスト用のSpringインメモリデータベース、SessionContext、およびアノテーションを使用しない場合のhbm.xml:

/**
 * Instantiates a H2 embedded database and the Hibernate session.
 */
public abstract class HibernateTestBase {

    private static EmbeddedDatabase dataSource;
    private static SessionFactory sessionFactory;
    private Session session;

    @BeforeClass
    public static void setupClass() {
        dataSource = new EmbeddedDatabaseBuilder().
                setType(EmbeddedDatabaseType.H2).
                addScript("file:SQLResources/schema-1.1.sql").
                addScript("file:SQLResources/schema-1.2.sql").
                build();
        Configuration configuration = new Configuration();
        configuration.addResource("hibernate-mappings/Cat.hbm.xml");
        configuration.setProperty("hibernate.dialect",
                "org.hibernate.dialect.Oracle10gDialect");
        configuration.setProperty("hibernate.show_sql", "true");
        configuration.setProperty("hibernate.current_session_context_class",
                "org.hibernate.context.internal.ThreadLocalSessionContext");
        StandardServiceRegistryBuilder serviceRegistryBuilder =
                new StandardServiceRegistryBuilder();
        serviceRegistryBuilder.applySetting(Environment.DATASOURCE, dataSource);
        serviceRegistryBuilder.applySettings(configuration.getProperties());
        StandardServiceRegistry serviceRegistry =
                serviceRegistryBuilder.build();
        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        sessionFactory.openSession();
    }

    @AfterClass
    public static void tearDown() {
        if (sessionFactory != null) {
            sessionFactory.close();
        }
        if (dataSource != null) {
            dataSource.shutdown();
        }
    }

    @Before
    public final void startTransaction() {
        session = sessionFactory.getCurrentSession();
        session.beginTransaction();
    }

    @After
    public final void rollBack() {
        session.flush();
        Transaction transaction = session.getTransaction();
        transaction.rollback();
    }

    public Session getSession() {
        return session;
    }

}

これらが必要になります:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>4.1.6.RELEASE</version>
</dependency>
<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <version>1.4.184</version>
  <scope>test</scope>
</dependency>
3
Adam

データソースがJNDIツリーにバインドされている場合:

configuration.setProperty("hibernate.connection.datasource", "Java:comp/env/jdbc/test");

それ以外で、使用するコードにDataSourceオブジェクトがある場合:

Java.sql.Connection conn = datasource.getConnection();
Session session = sessionFactory.openSession(conn);

最初の方法は、必要に応じてHibernateに接続ライフサイクルを処理させることをお勧めします。 2番目の方法では、不要になった接続を必ず閉じてください。

2
Tomas Narros

Springフレームワークを使用している場合は、LocalSessionFactoryBeanを使用してデータソースをHibernate SessionFactoryに注入します。

<beans>
    <bean id="YourClass"
        class="com.YourClass.
        <property name="sessionFactory">
            <ref bean="DbSessionFactory" />
        </property>     
    </bean>


    <bean id="dataSource" class="org.Apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName">
            <value>org.postgresql.Driver</value>
        </property>
        <property name="url">
            <value>jdbc:postgresql://localhost/yourdb</value>
        </property>
        <property name="username">
            <value>postgres</value>
        </property>
        <property name="password">
            <value>postgres</value>
        </property>     
    </bean>

    <bean id="DbSessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>     
        <property name="mappingResources">
            <list>
                <value>conf/hibernate/UserMapping.hbm.xml</value>               
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect"> org.hibernate.dialect.PostgreSQLDialect </prop>      
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.cache.use_second_level_cache"> true </prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
            </props>
        </property>
    </bean>
</beans>
1
nIKUNJ

javax.sql.DataSourceを使用してクラスを実装した場合、HibernateのDataSourceはプロパティを構成することで設定できます。

import javax.sql.DataSource;
public class HibernateDataSource implements DataSource {
    ...
}


import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
public class MyHibernateCfg {
    public void initialize() {
        HibernateDataSource myDataSource = new HibernateDataSource();
        Configuration cfg = new Configuration();
        // this is how to configure hibernate datasource
        cfg.getProperties().put(Environment.DATASOURCE, myDataSource);
        ...
    }
}


import org.hibernate.cfg.Configuration;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
public class TableClass {
    public void initialize() {
        MyHibernateCfg cfg = new MyHibernateCfg();
        Configuration conf = cfg.getCfg();
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
        SessionFactory sessionFactory = conf.buildSessionFactory(serviceRegistry);
        Session sessionFactory.openSession();
        ...
    }
}
1
user2601995

できないと思います。 Hibernate APIを使用すると、JDBCプロパティを構成して、接続自体を管理できるようにしたり、JNDI DataSourceの場所を指定して、そこに移動してフェッチしたりできますが、私はそうは思わない与えるそれはデータソースです。

Springを使用しているオフチャンスでは、より簡単です。LocalSessionFactoryBeanを使用してHibernateを構成し、それにDataSourceを注入します。 Springは必要な魔法をバックグラウンドで実行します。

1
skaffman

LocalContainerEntityManagerFactoryBeanを使用して、構成クラスでEntityManagerFactoryインスタンスを作成しました。

別のDataSourceを設定する必要がある場合は、実行時にエンティティマネージャーファクトリインスタンスで更新することができます。

@Service("myService")
public class MyService
{
....
    @Autowired
    private LocalContainerEntityManagerFactoryBean emf;
....
    public void replaceDataSource(DataSource dataSource)
    {
        emf.setDataSource(dataSource);
        emf.afterPropertiesSet();
    }
....
}

Hibernate 5.2.9 Finalで動作します。

0
user9117214