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();
セッションへの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);
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でテストされています。
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>
データソースが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番目の方法では、不要になった接続を必ず閉じてください。
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>
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();
...
}
}
できないと思います。 Hibernate APIを使用すると、JDBCプロパティを構成して、接続自体を管理できるようにしたり、JNDI DataSourceの場所を指定して、そこに移動してフェッチしたりできますが、私はそうは思わない与えるそれはデータソースです。
Springを使用しているオフチャンスでは、より簡単です。LocalSessionFactoryBean
を使用してHibernateを構成し、それにDataSourceを注入します。 Springは必要な魔法をバックグラウンドで実行します。
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で動作します。