I am new to hibernate and I don't fully understand how to choose between java configuration and xml in hibernate config file? Tutorials that I have watched seem to be out of date. So my question is what is the best and most up to date way of configuring a model to hibernate.
The following is my current approach which seems to be the only one working for me:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydatabase</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.pool_size">10</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL57InnoDBDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
<property name="hbm2ddl.auto">update</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.enable_lazy_load_no_trans">true</property>
<!-- <property name="hibernate.generate_statistics">true</property> -->
I am configuring my model in a java file as shown below:
public class HibernateUtil {
private static SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create your SessionFactory with mappings for every Entity in a specific package
Configuration configuration = new Configuration();
configuration.configure();
configuration.addAnnotatedClass(PersonModel.class);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
//SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
return sessionFactory;
} 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);
}
}
Is this the right way of doing it? or should it be done via XML file, if so can someone show me an example please?
Thanks in advance
Look at the following docs for examples:
For annotation mapping:
https://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-mapping
For xml mapping:
https://docs.jboss.org/hibernate/orm/3.3/reference/fr-FR/html/xml.html
Use of one of them it's up to you, for more details you can check this answer or this one
EDIT: mapping example in hibernate configuration file
<hibernate-configuration>
<session-factory>
<mapping package="test.animals"/>
<mapping class="test.Flight"/>
<mapping class="test.Sky"/>
<mapping class="test.Person"/>
<mapping class="test.animals.Dog"/>
<mapping resource="test/animals/orm.xml"/>
</session-factory>
</hibernate-configuration>
This way you can scan all entity classes at once
SessionFactory sessionFactory = new LocalSessionFactoryBuilder(yourDataSource())
.scanPackages("com.yourpackage.name")
.addProperties(properties)
.buildSessionFactory();
Related
I'm working on an E-Commerce App using Hibernate Framework. But I'm facing a problem during the execution. The test program throws an Exception :
Exception in thread "main" java.lang.ExceptionInInitializerError
at HibernateUtil.buildSessionFactory(HibernateUtil.java:19)
at HibernateUtil.<clinit>(HibernateUtil.java:9)
at Test.main(Test.java:10)
Caused by: java.lang.NullPointerException
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1708)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1617)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:692)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at HibernateUtil.buildSessionFactory(HibernateUtil.java:14)
... 2 more
My HibernateUtil :
import org.hibernate.*;
import org.hibernate.cfg.*;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return 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;
}
}
Hibernate.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>
<!-- local connection properties -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/ecom</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.pool_size">10</property>
<!-- dialect for MySQL -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="cache.use_query_cache">false</property>
<mapping class="Metier.Category"/>
<mapping class="Metier.Customer"/>
<mapping class="Metier.CustomerOrder"/>
<mapping class="Metier.orderedProduct"/>
<mapping class="Metier.orderedProductID"/>
<mapping class="Metier.Product"/>
</session-factory>
</hibernate-configuration>
Please tell me what is the source of the Exception.
Cheers.
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();
There is some questions with my code using hibernate .
My code as follows .
HibernateUtil.java
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
/**
* get sessionFactory
*
* #author YD
*
*/
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
sessionFactory = cfg.buildSessionFactory(serviceRegistry);
}
/**
* get sessionFactory from singleton pattern
*
* #return
*/
public static SessionFactory getInstance() {
if (sessionFactory == null) {
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
sessionFactory = cfg.configure().buildSessionFactory(
serviceRegistry);
}
return sessionFactory;
}
}
MainCode to get news in Action
/**
* get my news
*/
public void getNews() {
Session session = HibernateUtil.getInstance().getCurrentSession();
Transaction tx = session.beginTransaction();
// some operation
tx.commit();
}
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>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">
mysql_url
</property>
<property name="hibernate.connection.username">my_username</property>
<property name="connection.password">my_password</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</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.internal.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">update</property>
<!-- c3p0 connection pool -->
<property name="org.hibernate.c3p0.internal.C3P0ConnectionProvider">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.timeout">120</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">120</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">true</property>
<!-- mapping file -->
<mapping class="my.News />
</session-factory>
</hibernate-configuration>
I also use struts2 in my project. and my project in a web project deploying on tomcat 7.0.57.
The Problem is :
When I open the web page to get news,sometimes I got the Exception:
Struts Problem Report
Struts has detected an unhandled exception:
Messages:
nested transactions not supported
File: org/hibernate/engine/transaction/spi/AbstractTransactionImpl.java
Line number: 154
Stacktraces
org.hibernate.TransactionException: nested transactions not supportedorg.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:154)
org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1435)
sun.reflect.GeneratedMethodAccessor59.invoke(Unknown Source)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:356)
Why?
I know that if I use session.getCurrentSession() ** to operate session, then there is **no necessary to close session. I commit transaction in end every time. How it happened?
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.
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>