Hibernate configuration on runtime - java

I have hibernate.cfg.xml file.
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url"></property>
<property name="connection.username"></property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
.....................
This is the most interesting part of file.
Now i must set missing values: url, username, password.
I'm trying to do in such way:
public static void SetSessionFactory() {
try {
AnnotationConfiguration conf = new AnnotationConfiguration().configure();
// <!-- Database connection settings -->
conf.setProperty("connection.url", URL);
conf.setProperty("connection.username", USERNAME);
conf.setProperty("connection.password", PASSWORD);
SESSION_FACTORY = conf.buildSessionFactory();
} catch (Throwable ex) {
// Log exception!
throw new ExceptionInInitializerError(ex);
}
}
But it just loads my configuration from hibernate.cfg.xm and do not changing any property...
url, username, passoword - are command-line arguments so i must set them on runtime.

Try to call conf.configure(); here.
And properties may need to have hibernate prefix like "hibernate.connection.username"
Hope it helps.

Try like this it is working fine
AnnotationConfiguration conf = new AnnotationConfiguration().configure("/dronehibernate.cfg.xml");
conf.setProperty("hibernate.connection.url","jdbc:mysql://localhost/PAT_DRONE_DB1");
SessionFactory sessionFactory = conf.buildSessionFactory();
Session session = sessionFactory.openSession();
List<NetworkType> channelList = session.createQuery("from NetworkType").list();

Use constants from Environment class

Related

java.lang.NoClassDefFoundError: Could not initialize class com.DatabaseHandler.DBHandler

I'm trying to host my first backend server via heroku. I have already hosted a mysql server (also on heroku) that I have been able to connect to from my local using both my java servlet and mysql workbench.
I used heroku's git integration to push my servlet to their servers, and as far as I can tell, my tomcat server IS running. When I try to hit one of my urls I get an error message.
The only one I can see that matters is the last one.
java.lang.NoClassDefFoundError: Could not initialize class com.DatabaseHandler.DBHandler.
From what I can understand, this is being caused because my static initialization for my session handler is failing.
I've double checked all of my connections, made sure my mysql drivers were correct, added the mysql driver to the buildpath just in case heroku can't find it, and a host of other things.
Most of my google searches have come up fruitless with solutions I've already tried, or answers that don't pertain to my problem.
Article Controller
public class ArticleService {
Session session;
public ArticleService() {
this.session = DBHandler.getSessionFactory().openSession();
}
public List<Article> getAllArticles() {
List<Article> list = session.createQuery("from Article").list();
return list;
}
public ArticleModelView getArticlePage(int pageNumber, int itemsPerPage) {
ArticleModelView avm = new ArticleModelView();
Query q = session.createQuery("from Article");
q = q.setFirstResult(pageNumber*itemsPerPage);
q = q.setMaxResults(itemsPerPage);
avm.articles = q.list();
int temp = session.createQuery("from Article").list().size();
temp = temp % itemsPerPage == 0 ? temp/itemsPerPage - 1: temp/itemsPerPage;
avm.maxPageSize = temp;
return avm;
}
}
Database Handler
public class DBHandler
{
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
getSessionFactory().close();
}
}
Hibernate Config
<?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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">*******?reconnect=true</property>
<property name="hibernate.connection.password">******</property>
<property name="hibernate.connection.username">******</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping class="com.dailybagel.user.resources.User"/>
<mapping class="com.dailybagel.article.resources.Article"/>
</session-factory>
</hibernate-configuration>
When I visit that url with local host the application correctly pings the hosted mysql server and returns the contents of that table.
The goal is to get the hosted servlet to do that same thing.
So it looks like Heroku misplaces the Hibernate config file, or it's lost, or something of the sort. Adding your config variable to the Session Handler resolves the issue.
I don't really understand why it gets misplaced, but hopefully this will help someone!
static {
try {
Properties prop= new Properties();
prop.setProperty("hibernate.connection.url", "*********");
prop.setProperty("hibernate.connection.username", "********");
prop.setProperty("hibernate.connection.password", "********");
prop.setProperty("dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
sessionFactory = new AnnotationConfiguration()
.addPackage("com.dailybagel.user.resources")
.addPackage("com.dailybagel.article.resources")
.addAnnotatedClass(User.class)
.addAnnotatedClass(Article.class)
.addProperties(prop)
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
If anyone know why this happens, I'd love to know more about it

getting org.hibernate.HibernateException: No CurrentSessionContext configured! when trying to connect to heroku-postgresql Hibernate

I'm getting this error: org.hibernate.HibernateException: No CurrentSessionContext configured!
when trying to connect to Heroku Postgres DB.
this is my hibernate configuration (i called it: hibernateUser.cfg.xml):
<?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.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://ec2-54-243-213-188.compute-1.amazonaws.com:5432/dess6n165jarrv</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="hibernate.default_schema">dess6n165jarrv</property>
<property name= "hbm2ddl.auto">update</property>
<property name="hibernate.current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
enter code here
I'm implementing this as a singleton :
public static HibernateUserDAO getInstance(HttpServletResponse response) throws IOException
{
instance = new HibernateUserDAO();
if (instance == null)
{
userFactory = new Configuration().configure("hibernateUser.cfg.xml").addAnnotatedClass(AppUser.class).buildSessionFactory();
}
return instance;
}
public void addNewUser(AppUser user) throws UserExceptionHandler, IOException
{
Session session = null;
int id = 0;
try
{
session = userFactory.getCurrentSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
}catch (HibernateException e)
{
if (session.getTransaction() != null) session.getTransaction().rollback();
throw new HibernateException (e);
}finally
{
try
{session.close();}
catch (HibernateException e)
{
throw new UserExceptionHandler("Warnning!! connection did'nt close properly");
}
}
if (id != 0)
System.out.println("User created successfully");
}
enter code here
I'm getting the error on this line:
session = userFactory.getCurrentSession();
I think the error is in my configuration file but I cant see where is the problem is (I read a couple of examples and I copy it)
You need to set your connection parameters dynamically like this:
Map<String,String> jdbcUrlSettings = new HashMap<>();
String jdbcDbUrl = System.getenv("JDBC_DATABASE_URL");
if (null != jdbcDbUrl) {
jdbcUrlSettings.put("hibernate.connection.url", System.getenv("JDBC_DATABASE_URL"));
}
registry = new StandardServiceRegistryBuilder().
configure("hibernate.cfg.xml").
applySettings(jdbcUrlSettings).
build();
This way, they are not hard coded, and will pick up changes made by the platform. For more info see Using the DATABASE_URL with Hibernate.

Change location of hibernate.properties file while using hibernate.cfg.xml

We provide db credential in hibernate.cfg.xml as
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">url</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<session-factory>
<hibernate-configuration>
Either we can provide these properties here or in hibernate.properties in classpath. But I want them to come from an external file. I couldn't find a way in hibernate to change the path of default hibernate.properties file.
Please help.
[EDIT]
The method in java which generates sessionFactory object
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
// Create the session factory from hibernate.cfg.xml
Configuration configuration = new Configuration();
StandardServiceRegistryBuilder serviceRegistryBuilder =
new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
return configuration.buildSessionFactory(serviceRegistryBuilder.build());
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Programmatically, you can load XML and properties like this:
public class MyHibernate {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
URL r1 = MyHibernate.class.getResource("/hibernate.cfg.xml");
Configuration c = new Configuration().configure(r1);
try {
InputStream is = MyHibernate.class.getResourceAsStream("/hibernate.properties");
Properties props = new Properties();
props.load(is);
c.addProperties(props);
} catch (Exception e) {
LOG.error("Error reading properties", e);
}
return c.buildSessionFactory();
} catch (Throwable ex) {
LOG.error("Error creating SessionFactory", ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Through Spring
You can use a PropertiesFactoryBean to read-in the properties from your file and configure your LocalSessionFactoryBean:
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="hibernateProperties">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location">path-to-properties-file</property>
</bean>
</property>
...
</bean>
Hope it be useful.

Receiving org.hibernate.ResourceClosedException "This TransactionCoordinator has been closed"

I have a servlet, running on Tomcat 6, that uses Hibernate 4.1.6 and c3p0 0.9.1.2, and I am getting too much org.hibernate.ResourceClosedException, with the message "This TransactionCoordinator has been closed".
I've already checked that beginTransaction() and rollback() or commit() are done before the thread is reused by another call.
At hibernate.cfg.xml, I have
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.url">jdbc:mysql://host/database</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- mappings start here -->
...
</session-factory>
</hibernate-configuration>
and I am using a HibernateUtil.java to create a static sessionFactory for my application and I use it to control my transactions:
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
getSessionFactory().close();
}
public static void beginTransaction() {
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
}
public static void commit() {
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
}
public static void rollback() {
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback();
}
}
When I start using the database in a servlet, my code is basically this:
try {
HibernateUtil.beginTransaction();
// do stuffs
HibernateUtil.commit();
} catch (RuntimeException e) {
HibernateUtil.rollback();
throw e;
} catch (Exception e) {
HibernateUtil.rollback();
throw e;
}
Where am I doing wrong?
I have closed a session after completing transaction and in the new session i have used the object of previous session, this caused me an 'Transaction Coordinator has been closed'
I have edited the code to use new session object, now the error is resolved

hibernate main method call

I'm very new to Hibernate and just wanted to query the initial basics.
I've created my Hibernate bean as such...
package com.behaviour.chapter1;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class User {
private int userId;
private String firstName;
#Id
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
I've configured my hibernate.cfg.xml and db connection there. My question is simply, how do I actually call this from a main method and use it in Hibernate3.6.6? I was following a tutorial online but it was for Hibernate3.2 and it seems to be a bit different. If anyone could show me just a really simple main method calling this bean, creating a new user (that would create a user in this table) it would be greatly appreciated. Also - if anyone has any good Hibernate tutorial links that would be great :)
Thanks,
There are several ways of doing this, it is a matter of design choice, a basic way to achieve this will be to create the session factory from hibernate.cfg.xml file. Make sure the file can be located at your classpath.
And using the class below, create a Session Factory object which is then used to open up new Session's
public class HibernateUtil
{
private static final SessionFactory sessionFactory;
static
{
try
{
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
}
catch (Throwable ex)
{
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory()
{
return sessionFactory;
}
}
Now to create a new user, do:
public class DaoFactory
{
public void create(Object obj)throws Exception
{
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.save(obj);
session.getTransaction().commit();
}
}
Main
public static void main(String[] args)
{
try
{
User user = new User();
user.setFirstName("david99world");
DaoFactory factory = new DaoFactory();
factory.create(user);
}
catch(Exception ex)
{
ex.printStackTrace(System.out);
}
}
EDIT
Your hibernate.cfg.xml should look something like this:
<?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="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">none</property>
<mapping class="com.behaviour.chapter1.User"/>
</session-factory>
</hibernate-configuration>
I'm assuming you've set up your persistence.xml already. If so, you can use the following Java code. You'll have to substitute the "..." with your JDBC setup data and persistence unit.
private static final String PERSISTENCE_UNIT = "...";
final Map<String, String> properties = new HashMap<String, String>();
properties.put("javax.persistence.jdbc.driver", "...");
properties.put("javax.persistence.jdbc.url", "...");
properties.put("javax.persistence.jdbc.user", "...");
properties.put("javax.persistence.jdbc.password", "...");
final EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT, properties);
final EntityManager em = emf.createEntityManager();
User user = new User();
user.setUserID(0);
user.setFirstName("David");
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit();
HTH
Raku
Hibernate tutorials
Hibernate tutorial-1
Hibernate tutorial -2
Do you need a Session object to access the persistence unit. These objects are provided by SessionFactory objects.
Check the Hibernate reference guide.

Categories

Resources