I have new spring-boot project. I use gradle as build manager and Eclpice IDE. I want to use hibernate and try to get configurations from hibernate.cfg.xml file, but get
org.hibernate.HibernateException: /hibernate.cfg.xml not found
I store this file in resources folder, also I tried put it into META-INF folder.
folders structure:
HibernateUtil.java:
public class HibernateUtil {
private static SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory()
{
try
{
if (sessionFactory == null)
{
sessionFactory = new Configuration().configure().buildSessionFactory();
}
return sessionFactory;
} 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() {
// Close caches and connection pools
getSessionFactory().close();
}
}
If you want to read the files in the resources directory, you need to use the classloder to get the file.
In static method
HibernateUtil.class.getClassLoader().getResource("hibernate.cfg.xml").getFile();
non static method
getClass().getClassLoader().getResource("hibernate.cfg.xml").getFile();
and if the resource resides in any of the sub directories of resources, prefix the folder path while getting the resource
Example to get the resource in META-INF directory
getResource("META-INF/hibernate.cfg.xml");
But spring boot auto configures, just by adding dependencies in pom.xml and providing JPA related properties in application.properties
if your application is web Service,you should put hibernate.cfg.xml in WEB-INF floder.if your application is client service, you should put your hibernate.cfg.xml in src package.
Related
I'm using Hibernate withhout #annotations
I tried this code:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
private static StandardServiceRegistryBuilder builder;
static {
try {
Configuration configuration = new Configuration().configure();
configuration.configure("hibernate.cfg.xml");
builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (HibernateException ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Client code:
public static void main (String[] args) {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> customers = criteria.list();
for (Customer customer : customers) {
//print values
}
session.getTransaction().commit();
session.close();
}
Also here is important thing I want to know
What if I will create HibernateUtil class object in Client class?
HibernateUtil hibernateUtil = new HibernateUtil();
You can refer stackoverflow link:
What are the advantages and disadvantages of creating an Object in static block in Java?.
If you want SessionFactory to be created when your server or application starts, then static block can be used. else, go for static method approach. You can also use enums to create singleton.
So, you've got two questions there, one about this being the right approach to create a singleton, and the other about what happens if you create a HibernateUtil instance in the client.
First for the HibernateUtil
For the second question, you're fine if each client creates an instance of the HibernateUtil class, as the variable is static. If all goes according to plan, there will only be one Hibernate SessionFactory instance.
As for whether you have a correct Hibernate SessionFactory singleton implementation? That's a harder question to answer. While your code looks good, multiple classloaders can cause all sorts of unpredictable problems with singletons. If separate classloaders create an instance, you may have multiple instances of your singleton, a paradox you want to avoid.
EJB and Spring Singleton help
With the EJB specification, you can mark a session bean as a singleton. If you are using a Java web profile compliant server, I'd do that. If you are using Spring Boot, use the singleton facilities they provide. If it's a standalone application, keep an eye out for peculiar, non-singleton SessionFactory behavior.
I am new to Hibernate.
When I run my Hibernate program using Eclipse, it is able to find hibernate.cfg.xml file.
I put that file into src/main/resources folder.
But when I create executable jar and run my program using
java -jar SQ.jar
It is giving me following error
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.moodys.sonarqube.ExtractSQData.HibernateUtil.buildSessionFactory(HibernateUtil.java:20)
at com.moodys.sonarqube.ExtractSQData.HibernateUtil.<clinit>(HibernateUtil.java:9)
at com.moodys.sonarqube.ExtractSQData.SQ.getProjectDB(SQ.java:266)
at com.moodys.sonarqube.ExtractSQData.SQ.extractSQDataToDB(SQ.java:76)
at com.moodys.sonarqube.ExtractSQData.SQ.main(SQ.java:59)
Caused by: org.hibernate.HibernateException: /hibernate.cfg.xml not found
at org.hibernate.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:147)
at org.hibernate.cfg.Configuration.getConfigurationInputStream(Configuration.java:1405)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1427)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1414)
at com.moodys.sonarqube.ExtractSQData.HibernateUtil.buildSessionFactory(HibernateUtil.java:14)
... 4 more
Following is the code where I load my hibernate.cfg.xml file
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new AnnotationConfiguration().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);
}
}
Please advise me what I am doing wrong.
You can give the full path while configure it.
You can try this.
return new AnnotationConfiguration().configure("/resources/hibernate.cfg.xml").buildSessionFactory();
or
return new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();
You can try this one also if you are using hibernate 4.3+
configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
StandardServiceRegistryBuilder serviceBuilder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(serviceBuilder.build());
I'm trying to use hibernate with spring 3 mvc but at the moment I get this exception thrown. I think I need to define my hibernate.cfg.xml somewhere, but not sure where?
I basically followed this example here http://www.nabeelalimemon.com/blog/2010/05/spring-3-integrated-with-hibernate-part-a/ And in particularly saw this line of code there that suppose to "magically" find my hibernate.cfg file using this:
return new Configuration().configure().buildSessionFactory();
I'm guessing that is not correct? i currently have my hibernate.cfg file inside src/com/jr/hibernate/
below is my cfg file:
<?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/racingleague</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="hibernate.format_sql">true</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="hibernate.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="hibernate.show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--property name="hbm2ddl.auto">update</property-->
<mapping resource="com/jr/model/hibernateMappings/user.hbm.xml"/>
</session-factory>
</hibernate-configuration>
my hibernate utils class:
package com.jr.utils;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
private static final SessionFactory sessionFactory = buildSessionFactory();
public 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);
}
}
}
which gets called bu this abstract class:
package com.jr.db;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import com.jr.utils.HibernateUtils;
public abstract class DbWrapper<T> {
private static SessionFactory sessionFactory = null;
private static Session session;
public DbWrapper() {
setSessionFactory();
}
private void setSessionFactory() {
sessionFactory = HibernateUtils.buildSessionFactory();
session = sessionFactory.getCurrentSession();
}
public boolean addNewItem(T dbItem) {
try {
session.getTransaction().begin();
session.save(dbItem);
session.getTransaction().commit();
} catch (Exception e) {
System.err.println("error exception when adding new item to table"
+ e);
} finally {
session.close();
sessionFactory.close();
}
return false;
}
public abstract boolean removeItem(String uid);
public abstract boolean modifyItem(String uid, T item);
}
And here is the controller that originally does some hibernate stuff:
private Logger logger = Logger.getLogger(UserController.class);
private UserDb userDb;
#RequestMapping(value = "/user/registerSuccess", method = RequestMethod.POST)
public String submitRegisterForm(#Valid User user, BindingResult result) {
// validate the data recieved from user
logger.info("validate the data recieved from user");
if (result.hasErrors()) {
logger.info("form has "+result.getErrorCount()+" errors");
return "account/createForm";
} else{
// if everthings ok, add user details to database
logger.info("if everthings ok, add user details to database");
userDb = new UserDb();
userDb.addNewItem(user);
// display success and auto log the user to the system.
return "account/main";
}
}
Cheers in advance. I also have all my table hibvernate xml mappings in the same location as my hibernate.cfg.xml file
Instead of placing hibernate.cfg.xml file under src/com/jr/hibernate/ directory, place it under src directory. It will then automatically appear in WEB-INF/classes directory, as mentioned by the folks here.
hibernate.cfg.xml must be found in the root of the classpath when the webapp is started.
If you are using maven to build the project, put hibernate.cfg.xml in the src/main/resources directory so that when you build the war package, it will be automatically be placed in /WEB-INF/classes.
If not using maven, place the file directly in your WEB-INF/classes directory.
hibernate.cfg.xml should be in WEB-INF/classes. Alternatively, you can load it from a custom location by passing the corresponding argument to the configure(..) method.
If you using Maven you should put file hibernate.cfg.xml in following path /src/main/java/resources/hibernate.cfg.xml in Intellij IDEA. Then, in your run application class just insert line:
SessionFactory factory = new
Configuration().configure("hibernate.cfg.xml").addAnnotatedClass().buildSessionFactory();
In IntelliJ go to "Open Project Settings" >> Modules >> Hibernate and target your hibernate.cfg.xml file used in your project.
I have the same problem and moved hibernate.cfg.xml to the src/main/resources directory solved, it will be automatically be placed in /WEB-INF/classes.
Even if i had hibernate.cfg.xml under src folder, i get
org.hibernate.HibernateException: /hibernate.cfg.xml not found
after running mvn clean install. With Try and error i was able to resolve it by removing hibernate.cfg.xml from src folded and add to to somewhere else. Run the app(It is a main class in my case). During this I still get the error. and add it back to src folder and rum the main class. It worked!
I created a project with following structure:
HibernateUtil:
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
Configuration configuration = new Configuration().configure( "C:\\Users\\Nikolay_Tkachev\\workspace\\hiberTest\\src\\logic\\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;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
at line
Configuration configuration = new Configuration().configure( "C:\\Users\\Nikolay_Tkachev\\workspace\\hiberTest\\src\\logic\\hibernate.cfg.xml");
I have error
Initial SessionFactory creation
failed.org.hibernate.HibernateException:
C:\Users\Nikolay_Tkachev\workspace\hiberTest\src\logic\hibernate.cfg.xml
not found Exception in thread "main"
java.lang.ExceptionInInitializerError at
logic.HibernateUtil.buildSessionFactory(HibernateUtil.java:19) at
logic.HibernateUtil.(HibernateUtil.java:9) at
logic.Main.main(Main.java:12) Caused by:
org.hibernate.HibernateException:
C:\Users\Nikolay_Tkachev\workspace\hiberTest\src\logic\hibernate.cfg.xml
not found at
org.hibernate.internal.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:173)
at
org.hibernate.cfg.Configuration.getConfigurationInputStream(Configuration.java:1947)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1928)
at logic.HibernateUtil.buildSessionFactory(HibernateUtil.java:14)
... 2 more
What is the reason for the error and how do I fix it?
Give the path relative to your project.
Create a folder called resources in your src and put your config file there.
configuration.configure("/resources/hibernate.cfg.xml");
And If you check your code
Configuration configuration = new Configuration().configure( "C:\\Users\\Nikolay_Tkachev\\workspace\\hiberTest\\src\\logic\\hibernate.cfg.xml");
return new Configuration().configure().buildSessionFactory();
In two lines you are creating two configuration objects.
That should work(haven't tested) if you write,
Configuration configuration = new Configuration().configure( "C:\\Users\\Nikolay_Tkachev\\workspace\\hiberTest\\src\\logic\\hibernate.cfg.xml");
return configuration.buildSessionFactory();
But It fails after you deploy on the server,Since you are using system path than project relative path.
Somehow placing under "src" folder didn't work for me.
Instead placing cfg.xml as below:
[Project Folder]\src\main\resources\hibernate.cfg.xml
worked.
Using this code
new Configuration().configure().buildSessionFactory().openSession();
in a file under
[Project Folder]/src/main/java/com/abc/xyz/filename.java
In addition have this piece of code in hibernate.cfg.xml
<mapping resource="hibernate/Address.hbm.xml" />
<mapping resource="hibernate/Person.hbm.xml" />
Placed the above hbm.xml files under:
EDIT:
[Project Folder]/src/main/resources/hibernate/Address.hbm.xml
[Project Folder]/src/main/resources/hibernate/Person.hbm.xml
Above structure worked.
You can put the file "hibernate.cfg.xml" to the src folder (src\hibernate.cfg.xml) and then init the config as the code below:
Configuration configuration = new Configuration();
sessionFactory =configuration.configure().buildSessionFactory();
This is an reality example when customize folder structure:
Folder structure, and initialize class HibernateUtil
with:
return new Configuration().configure("/config/hibernate.cfg.xml").buildSessionFactory();
mapping:
with customize entities mapping files:
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="com.vy.entities.Users"/>
<mapping class="com.vy.entities.Post"/>
<mapping resource="config/Users.hbm.xml"/>
<mapping resource="config/Post.hbm.xml"/>
</session-factory>
</hibernate-configuration>
(Note: Simplest way, if you follow default way, it means put all xml config files inside src folder, when build sessionFactory, only:
return new Configuration().configure().buildSessionFactory();
)
For anyone interested: if you are using Intellj, just simply put hibernate.cfg.xml under src/main/resources.
try below code it will solve your problem.
Configuration configuration = new Configuration().configure("/logic/hibernate.cfg.xml");
My problem was that i had a exculding patern in the resorces folder.
After removing it the
config.configure();
worked for me. With the structure
src/java/...HibernateUtil.java and cfg file under src/resources.
Another reason why this exception occurs is if you call the configure method twice on a Configuration or AnnotatedConfiguration object like this -
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass(MyClass.class);
//Use this if config files are in src folder
config.configure();
//Use this if config files are in a subfolder of src, such as "resources"
config.configure("/resources/hibernate.cfg.xml");
Btw, this project structure is inside eclipse.
Using configure() method two times is responsible the problem for me. Instead of using like this :
Configuration configuration = new Configuration().configure();
configuration.configure("/main/resources/hibernate.cfg.xml");
Now, I am using like this, problem does not exist anymore.
Configuration configuration = new Configuration();
configuration.configure("/main/resources/hibernate.cfg.xml");
P.S: My hibernate.cfg.xml file is located at "src/main/resources/hibernate.cfg.xml",too.
The code belove works for me. at hibernate-5
public class HibernateUtil {
private static SessionFactory sessionFactory ;
static {
try{
Configuration configuration = new Configuration();
configuration.configure("/main/resources/hibernate.cfg.xml");
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
}
catch(Exception e){
e.printStackTrace();
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
In case of a Maven Project, create a folder named resources under src/main folder and add the resources folder as a source folder in your classpath.
You can do that by going to Configure Build Path and then clicking Add Folder to the Sources Tab.
Then check the resources folder and click Apply.
Then just use :
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
I have been learning to use hibernate for a couple of months.
I am finding it difficult in deciding how to configure hibernate to work on a test database.
I have a hibernate.cfg.xml with db parameters given as elements.
<property name="connection.url">
jdbc:postgresql://localhost/mydb
</property>
<property name="connection.username">me</property>
<property name="connection.password">mypasswd</property>
My web app uses a HibernateUtil class which loads the configuration as below
class HibernateUtil {
private Class<T> persistentClass;
private static SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
...
My dao implementation uses the above class to get the Session
public class BaseDaoImpl<T, ID extends Serializable>{
private Session session;
...
public Session getSession() {
if (session == null || !session.isOpen()){
return HibernateUtil.getCurrentSession();
}else{
return session;
}
}
public T findById(ID id){
T entity = (T) getSession().load(getPersistentClass(), id);
return entity;
}
This is OK as long as I work on the mydb configured in cfg.xml file.But for my tests I am using another database which is given in a test.properties file
test.db.url=jdbc:postgresql://localhost/mytestdb
test.db.driver=org.postgresql.Driver
test.db.username=testme
test.db.password=testpass
The only way I can make hibernate work on mytestdb is to manually replace every db related property in cfg.xml.I would very much like to use test_hibernate.cfg.xml with the test db properties,but since the configuration is done in a static block in HibernateUtil ,that won't work.
Is there a better way of configuring hibernate for these two databases?
I am using ant as build tool..
Any suggestions would be most welcome
jim
I would very much like to use test_hibernate.cfg.xml with the test db properties,but since the configuration is done in a static block in HibernateUtil
So then don't create your configuration in a static block.
Instead, create a class which accepts a parameter for the path to the configuration file (a la Spring's LocalSessionFactoryBean) which returns the Configuration/SessionFactory to use. Or if you truly want to stick with HibernateUtil (which is a strategy very much recommended against in any production setting), change it to read a property or system environment variable to read the configuration.