I have created a maven project with hibernate 5.4 and successfully created DAOs now when I try to get Hibernate Session via getSessionFactory().getCurrentSession() I get Exception org.hibernate.HibernateException: No CurrentSessionContext configured! although I have already added
<property name="hibernate.current_session_context_class">thread</property> in hibernate.cfg.xml file. Already checked several forums including this question org.hibernate.HibernateException: No CurrentSessionContext configured but unable to solve it,
Here is the 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.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">onetozero</property>
<property name="hibernate.connection.url">jdbc:mysql://192.168.0.112:3306/ecdis</property>
<property name="hibernate.connection.username">root1</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping class="Domain.Route"/>
<mapping class="Domain.RoutePoint"/>
</session-factory>
</hibernate-configuration>
HibernateSession Class
public class HibernateSession {
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;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
and this is how I am using getting the List via DAO
public List<T> list() {
Session session = HibernateSession.getSessionFactory().getCurrentSession();
CriteriaQuery<T> query = session.getCriteriaBuilder().createQuery(entityClass);
query.select(query.from(entityClass));
return session.createQuery(query).getResultList();
}
I am new new to Java and Hibernate, also not using any framework atm so a little detail can also go along the way. TIA
Use HibernateSession.getSessionFactory().openSession() rather than getCurrentSession() to get session, then session factory will bind session to current context as you are using current session context class thread not JTA.Details here
Maybe it is a simple question, but I can't find out this situation of relations in Hibernate.
I have these Entities:
#Entity
public class User {
...
#OneToMany(mappedBy = "user")
private Set<Conversation> posts = new HashSet<Conversation>();
...
}
#Entity
public class Conversation {
...
#OneToMany(mappedBy = "conversation")
private Set<Message> messages = new HashSet<Message>();
...
}
#Entity
public class Message { ... }
and then I want create User with Conversation and Message at once. Idea should be like this:
User user = new User();
user.getPosts().add(new Conversation(){
{
getMessages().add(new Message());
}
});
session.persist(user);
But just User is saved in database - why isn't it all? Because of default LAZY fetching? Could my idea be implemented somehow?
PS: Of course I know about the solution of persisting each of the entities, but I am used to do like this in other frameworks like nette or Django, so I can't get out of my head.
PPS: I found out that problem is in default CascadeType. Could it be set on globally, e.g. in Hibernate config XML? Is it a good idea (by performance point of view - it is persisted each time on "superpersist" or only in case of changes)?
PPPS: I also found out (opposite to Django) that I have to set FK ex-post for each item added to collection. It is natural (because of selected pure Set type), but new for me. Which approach would you recommend me? Required FK as argument in constructor on item Entity e.g.:
Class Message{
Message(Conversation conversation){
setConversation(conversation);
}
...
}
or make a method for adding where FK sets inside e.g.:
Class Conversation{
...
public void addMessage(Message msg){
msg.setConversation(this);
getMessages().add(msg);
}
...
}
?
Making Session + configure XML.
private final static String CFG = "hibernate-cfg.xml";
private final static String SCRIPT_FILE = "query.sql";
private static SessionFactory sessionFactory;
private static ServiceRegistry buildRegistry() {
return new StandardServiceRegistryBuilder()
.configure(CFG)
.build();
}
private static Metadata getMetaData() {
return new MetadataSources(buildRegistry()).getMetadataBuilder().build();
}
private static SessionFactory buildSessionFactory() {
return getMetaData().getSessionFactoryBuilder().build();
}
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
sessionFactory = buildSessionFactory();
}
return sessionFactory;
}
public static Session getSession(){
try {
return getSessionFactory().openSession();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
and the hibernate-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>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/learnme
</property>
<property name="connection.username">root</property>
<property name="connection.password"/>
<property name="connection.pool_size">100</property>
<!-- SQL dialect -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQL5Dialect
</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>
<!-- Display all generated SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping class="learnme.hibernate.entities.User"/>
<mapping class="learnme.hibernate.entities.Conversation"/>
<mapping class="learnme.hibernate.entities.Message"/>
</session-factory>
</hibernate-configuration>
According to this and this
you need to have this in your persistence.xml file to set it globally:
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<cascade-persist/>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
The mapping file has to be located either in the default location,
META-INF/orm.xml, or in another location that is specified explicitly
in the persistence unit definition (in persistence.xml).
Hibernate does not create any tables:
I got a Tomcat server where my jsf/hibernate project runs on. The database server is a MySQL server. Starts without problems but does not create any tables.
I made a new project without the Tomcat server and any other stuff. Only the Hibernate related code. Still no errors and warnings, but also no tables created.
Hibernate config (hibernate.cfg.xml):
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/3bt_database</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="hbm2ddl.auto">create</property>
<mapping class="model.Testtable"/>
</session-factory>
</hibernate-configuration>
HibernateUtil:
public class HibernateUtil {
private static final SessionFactory sessionfactory = buildSessionFactory();
public static SessionFactory buildSessionFactory() throws HibernateException {
try {
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
return configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionfactory(){
return sessionfactory;
}
}
StartStopListener:
#WebListener
public class StartStopListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
HibernateUtil.getSessionfactory().openSession();
}
#Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
HibernateUtil.getSessionfactory().close();
}
}
Testtable:
#Entity
#Table(name="tblTest")
public class Testtable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int testID;
private String testname;
}
Please do not tell me to create them manually. This is not the answer I am looking for.
try to prepend hibernate. in every propery name
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/3bt_database</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.hbm2ddl.auto">create</property>
<mapping class="model.Testtable"/>
</session-factory>
</hibernate-configuration>
Update :-
Provide one more property. try at beginning ..
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
//or try with
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
(Posted on behalf of the OP).
I solved the problem. The mapping setting in the XML was no working properly. This link helped me out very much.
I have created a simple Member Model Class and trying to retrieve all the members from the DB using Hibernate.
The hibernate.cfg.xml is as follows :
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</property>
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver://192.168.0.112:1433;DatabaseName=WBSEDCL</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">Asdf#123</property>
<property name="hibernate.connection.autocommit">true</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>
<property name="show_sql">true</property>
<!-- Mapping files -->
<mapping resource="Member.hbm.xml"/>
</session-factory>
</hibernate-configuration>
The Code For List members is as follows :
#SuppressWarnings("deprecation")
public static ArrayList<Member> listMembers(){
Session sessionNew = null;
ArrayList<Member> membrArray = new ArrayList<Member>();
try{
/* This step will read hibernate.cfg.xml and prepare hibernate for use */
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
SessionFactory sessionFactoryNew = configuration.buildSessionFactory(ssrb.build());
sessionNew = sessionFactoryNew.openSession();
String SQL_QUERY ="SELECT * FROM Member membr";
Query query = sessionNew.createQuery(SQL_QUERY);
for(Iterator it=query.iterate();it.hasNext();){
Object[] row = (Object[]) it.next();
Member membr_obj = new Member((String)row[0],(String)row[1],(String)row[2],(String)row[3],(String)row[4],(String)row[5],(String)row[6],(String)row[7],
(String)row[8],(String)row[9],(String)row[10],(String)row[11],(String)row[12],(String)row[13],(String)row[14],(String)row[15],(String)row[16],(String)row[17],
(String)row[18],(String)row[19],(String)row[20],(String)row[21],(String)row[22],(String)row[23],(String)row[24],(String)row[25],(String)row[26],
(String)row[27],(String)row[28],(String)row[29],(String)row[30],(String)row[31],(String)row[32],(String)row[33],(String)row[34],(String)row[35],
(String)row[36],(String)row[37],(String)row[38],(String)row[39],(String)row[40],(String)row[41],(String)row[42],(String)row[43],
(String)row[44],(String)row[45],(String)row[46],(String)row[47],(String)row[48],(String)row[49],(String)row[50],(String)row[51],(String)row[52],(String)row[53]);
membrArray.add(membr_obj);
}
}
catch(Exception exception){
System.out.println("Exception in listMember Function in PersistenceManager");
exception.printStackTrace();
}
finally{
/* Actual contact insertion will happen at this step*/
sessionNew.flush();
sessionNew.close();
}
return membrArray;
}
Whenever the code is executed and the method is invoked by a calling function then a nullpointerexception is thrown at
sessionNew.flush();
sessionNew.close();
Within The finally Block.
What am I doing wrong ?
sessionNew is not initialized as you expect it to be. There seems to be an exception thrown either before its initialized or at the point of initializing it. The code should have run the catch block sysout statement after the exception is thrown. Since Finally block always run, it just gets executed calling flush() on a null object. Please check why sessionNew is not getting initialized. Try to debug and check it.
I have two different config file for two different database and each one of them as there sessions open. Below is the code.
FYI - for security reasons i removed all my credential and have dummy one placed in my config files
one.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>
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="connection.url">URL</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.username">userName</property>
<property name="connection.password">Password</property>
<mapping class="com.ClassNameOfTheTable" />
</session-factory>
</hibernate-configuration>
Second.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>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="hibernate.connection.url">url</property>
<property name="hibernate.connection.username">userName</property>
<property name="hibernate.connection.password">password</property>
<mapping class="com.tableClassName" />
</session-factory>
</hibernate-configuration>
HibernateStratApp class(where i set the configured file)
package com.tn.gov;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class HibernateStartApp {
private static final SessionFactory sessionFactory = buildSessionFactory1();
private static final SessionFactory sessionFactory1 = buildSessionFactory2();
Session session=null;
Transaction transaction = null;
private static SessionFactory buildSessionFactory1() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure("one.cfg.xml").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 getSessionFactoryOne() {
return sessionFactory;
}
public static SessionFactory getSessionFactoryTwo(){
return sessionFactory1;
}
private static SessionFactory buildSessionFactory2() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure("two.cfg.xml").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);
}
}
}
And by opening and closing sessions i am retrieving the values.
But i am geting failed.org.hibernate.exception.JDBCConnectionException: Error calling Driver#connect when i try to connect.
i could able to figure this out, It was the problem with the URL which i was pointing to, That weird, that the error message dint printed it out correct.