Connect to a database dynamically in hibernate - java

So I have multiple pluggable databases (PDBs) and I want to connect to any one of them dynamically using Hibernate. How do I achieve such functionality?
To connect to PDB1 (and likewise for other PDBs), I have:
protected void setupPdb1() {
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure("hibernate-1.cfg.xml") // configures settings from hibernate.cfg.xml
.build();
try {
sessionFactory1 = new MetadataSources(registry).buildMetadata().buildSessionFactory();
} catch (Exception ex) {
StandardServiceRegistryBuilder.destroy(registry);
throw new RuntimeException(ex);
}
}
My hibernate config file corresponding to PDB1 is as follows:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:oracle:thin:#//localhost:1521/pdb1.oradev.oraclecorp.com</property>
<property name="connection.username">test</property>
<property name="connection.password">password12</property>
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="dialect">org.hibernate.dialect.Oracle12cDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<property name="current_session_context_class">thread</property>
<mapping class="net.codejava.hibernate.Book" />
</session-factory>
</hibernate-configuration>
The issue with this approach is there is one config file for each PDB. How do I dynamically select the PDB to connect to using Hibernate?

it depends on your strategy, what is the trigger to switch database ?

Related

first Hibernate test gives error [EDITED]

I'm an Hibernate beginner user, I created a very simple application to test it !
But I get this error in the console :
Initial SessionFactory creation failed.org.hibernate.HibernateException: Dialect class not found: org.openmeetings.app.hibernate.utils.MySQL5MyISAMDialect
Exception in thread "main" java.lang.ExceptionInInitializerError
at util.HibernateUtil.buildSessionFactory(HibernateUtil.java:20)
at util.HibernateUtil.<clinit>(HibernateUtil.java:10)
at DAO.services.addProduit(services.java:9)
at test.main(test.java:11)
Caused by: org.hibernate.HibernateException: Dialect class not found: org.openmeetings.app.hibernate.utils.MySQL5MyISAMDialect
at org.hibernate.dialect.DialectFactory.buildDialect(DialectFactory.java:81)
at org.hibernate.dialect.DialectFactory.buildDialect(DialectFactory.java:42)
at org.hibernate.cfg.SettingsFactory.determineDialect(SettingsFactory.java:422)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:128)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
at util.HibernateUtil.buildSessionFactory(HibernateUtil.java:15)
... 3 more
My Test class :
import DAO.services;
import DAO.Produit;
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
services s = new services();
Produit p = new Produit("PC","Sony Vaio",(double )7500);
s.addProduit(p);
}
}
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">
<!-- Generated file - Do not edit! -->
<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory>
<!-- User / Password -->
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- Database Settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- for performance reasons changed to MyISAM from org.hibernate.dialect.MySQLInnoDBDialect -->
<property name="dialect">org.openmeetings.app.hibernate.utils.MySQL5MyISAMDialect</property>
<property name="connection.url">jdbc:mysql://localhost:3306/gestProd</property>
<property name="hibernate.connection.CharSet">utf8</property>
<property name="hibernate.connection.characterEncoding">utf8</property>
<property name="hibernate.connection.useUnicode">true</property>
<!-- Database Scheme Auto Update -->
<property name="hbm2ddl.auto">update</property>
<!-- properties -->
<property name="show_sql">true</property>
<property name="use_outer_join">false</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--
<property name="connection.provider_class ">org.hibernate.connection.C3P0ConnectionProvider</property>
-->
<property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.generate_statistics">false</property>
<property name="hibernate.cache.use_structured_entries">false</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">2</property>
<property name="hibernate.c3p0.idle_test_period">100</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.timeout">100</property>
<!-- mapping files -->
<mapping resource="DAO/Categorie.hbm.xml"/>
<mapping resource="DAO/Produit.hbm.xml"/>
</session-factory>
</hibernate-configuration>
service.java :
package DAO;
import org.hibernate.Session;
import util.HibernateUtil;
public class services {
public void addProduit(Produit p){
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.save(p);
session.getTransaction().commit();
}
}
AND finally 2 classes for my objects ( Produit and Categorie ) and their Configuration files !
What do you think may be the source of this error ?
Thank you :)
The dialect for MySql with MyISAM(if that is what you have) should be:
org.hibernate.dialect.MySQLMyISAMDialect

how to map classes in hibernate using the class attribute?

I have a problem in my maven project
click the links below to see it
I added this to my hibernate.cfg but didn't work
<mapping package="com.redpass.entities"/>
<mapping class="com.redpass.entities.MyReference"/>
console error
Project Explorer
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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/avocatbd</property>
<property name="connection.username">root</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- <mapping package="com.redpass.entities"/>
<mapping class="com.redpass.entities.MyReference"/> -->
</session-factory>
</hibernate-configuration>
I should add this:
configuration.configure("hibernate.cfg.xml");
return configuration
.buildSessionFactory(new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.build());
to my HibernateUtil Class to tell that we want to configure using the hibernate.cfg.xml file and map the classes like this:
<mapping class="com.redpass.entities.Partie"/>
<mapping class="com.redpass.entities.Societe"/>

MySQLNonTransientConnectionException: No operations allowed after connection closed

I am hoping someone can help me. My database connection keeps getting closed and will not reopen so I am having to restart my application every few hours.
I have seen other answers here and have tried implementing them but they dont seem to make any difference. My JDBC url has autoReconnect=true and I am using hibernate with a c3p0 connection pool.
Any help would be great!
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.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/devenv38?autoReconnect=true</property>
<property name="hibernate.connection.username">devenv38</property>
<property name="hibernate.connection.password">devenv38</property>
<property name="hibernate.connection.autoReconnect">true</property>
<property name="hibernate.connection.autoReconnectForPools">true</property>
<property name="connection.is-connection-validation-required">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Use the C3P0 connection pool provider -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="c3p0.acquire_increment">5</property>
<property name="c3p0.max_size">500</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.idleConnectionTestPeriod">120</property>
<property name="c3p0.initialPoolSize">25</property>
<property name="c3p0.min_size">25</property>
<property name="c3p0.numHelperThreads">15</property>
<property name="c3p0.timeout">0</property> <!-- seconds -->
<property name="hibernate.show_sql">false</property>
<property name="hibernate.format_sql">false</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- resources -->
<mapping class="entities.Story" />
<mapping class="entities.User" />
</session-factory>
Database Connection Class
public class DatabaseConnection
{
static SessionFactory sf;
private DatabaseConnection()
{
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()).buildServiceRegistry();
sf = configuration.buildSessionFactory(sr);
}
public static Session getSession()
{
if (sf == null)
{
new DatabaseConnection();
}
return sf.openSession();
}
}
Example usage
Session session = DatabaseConnection.getSession();
Transaction txn = session.beginTransaction();
User user = new User();
user.setUsername("JUNIT USER 1");
user.setEmail("test#test.com");
user.setPassword("Test Password");
session.save(user);
txn.commit();

Use Two hibernate.cfg.xml files in a Application

how to specify two hibernate configurations for a one application,
i have created two hibernate files and mention them in SessionFactory.util
hibernateMaster.cfg.xml file is working fine..
but when shut down Master database server and try to use application with hibernateMaster.cfg.xml and retrieve data it gives me "null"
but if i restart the Application it is working fine with hibernateMaster.cfg.xml file
here are my hibernate files
hibernateMaster.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database Connection Settings -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://192.168.232.143:3306/cps</property>
<property name="hibernate.connection.username">gaiz</property>
<property name="hibernate.connection.password">mysql</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping resource="lib/driver/mappings/Patient.hbm.xml"/>
<mapping resource="lib/driver/mappings/Allergy.hbm.xml"/>
<mapping resource="lib/driver/mappings/Hospital.hbm.xml"/>
<mapping resource="lib/driver/mappings/StatStaff.hbm.xml"/>
<mapping resource="lib/driver/mappings/StatWard.hbm.xml"/>
<mapping resource="lib/driver/mappings/User.hbm.xml"/>
<mapping resource="lib/driver/mappings/UserRole.hbm.xml"/>
<mapping resource="lib/driver/mappings/UserLog.hbm.xml"/>
</session-factory>
</hibernate-configuration>
hibernateSlave.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database Connection Settings -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://192.168.232.144:3306/cps</property>
<property name="hibernate.connection.username">gaiz2</property>
<property name="hibernate.connection.password">mysql</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping resource="lib/driver/mappings/Patient.hbm.xml"/>
<mapping resource="lib/driver/mappings/Allergy.hbm.xml"/>
<mapping resource="lib/driver/mappings/Hospital.hbm.xml"/>
<mapping resource="lib/driver/mappings/StatStaff.hbm.xml"/>
<mapping resource="lib/driver/mappings/StatWard.hbm.xml"/>
<mapping resource="lib/driver/mappings/User.hbm.xml"/>
<mapping resource="lib/driver/mappings/UserRole.hbm.xml"/>
<mapping resource="lib/driver/mappings/UserLog.hbm.xml"/>
</session-factory>
</hibernate-configuration>
SessionFactoryUtil.java
package lib;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import core.resources.statisticalResource;
public class SessionFactoryUtil {
//This class creates a session factory object by looking at the hibernate configuration (hibernate.cfg.xml)
private static SessionFactory sesFactory;
private static ServiceRegistry sesRegistry;
static Configuration cfg;
static{
try{
cfg= new Configuration().configure("lib/hibernateMaster.cfg.xml");
sesRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
sesFactory=cfg.buildSessionFactory(sesRegistry);
try{
Session session = SessionFactoryUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
System.out.println("Connected to Master Database Server");
}
catch(Throwable ex){
cfg= new Configuration().configure("lib/hibernateSlave.cfg.xml");
sesRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
sesFactory=cfg.buildSessionFactory(sesRegistry);
System.out.println("Connected to Slave Database Server");
}
}
catch(Throwable ex){
System.out.println("Master & Slave Database Error.");
System.err.println("Initial SessionFactory Creation Failed"+ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sesFactory;
}
}
i dnt knw whether i have done something wrong on have done something wrong in SessionFactoryUtil.java .
Your problem is that you initialize your factory in a static way.
static{
...
}
That code is executed only once, when you start your application. That way when you shut down your master server hibernate stills asking for it.
You should initialize both configurations and use the main, if exists, or secondary in other case. You can do this in the getSessionFactory() method, that is executed each time the method is call, but not in an static initializer.

Hibernate does not see data inserted from external application

I am using Hibernate as an ORM for a server daemon.
This code returns no items if the table associated is empty at run time but has an item added outside of hibernate.
public static List<QueueItem> queue()
{
SessionFactory factory = HibernateUtil.getSessionFactory();
Session session = factory.openSession();
session.flush();
session.clear();
#SuppressWarnings("unchecked")
List<QueueItem> topList = session.createQuery("FROM QueueItem i ORDER BY i.id asc").setMaxResults(3).list();
session.close();
return topList;
}
Here is the hibernate config
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://10.10.1.4/lanjukebox_test</property>
<property name="hibernate.connection.username">ussqldev</property>
<property name="hibernate.connection.password">ussqldev</property>
<property name="hibernate.jdbc.batch_size">25</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">validate</property>
<!-- List of XML mapping files -->
<mapping resource="usagisoft/lan/jukebox/domain/entities/Song.hbm.xml"/>
<mapping resource="usagisoft/lan/jukebox/domain/entities/Id3.hbm.xml"/>
<mapping resource="usagisoft/lan/jukebox/domain/entities/QueueItem.hbm.xml"/>
<mapping resource="usagisoft/lan/jukebox/domain/entities/Vote.hbm.xml"/>
<mapping resource="usagisoft/lan/jukebox/domain/entities/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
If I create an object and persist it from within the application it works fine, If there is already data in the table and I insert the data it finds the other objects, the issue arises as soon as the table is empty during run time.
This is a big issue because another application handles the inserting of data for these objects.
I am using hibernate 4.2.7.Final with Java 1.7(jdk1.7.0_45) in eclipse.
You can resolve this problem since
hibernate.cfg.xml
adding this tag:
<property name="hibernate.connection.autocommit">true</property>

Categories

Resources