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
Related
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).
I am trying to create a basic hibernate application using hibernate 5.2.10 release. When I run it it says
org.hibernate.HibernateException: Unable to make JDBC Connection [jdbc:mysql//localhost:3306/hibernatedb]
hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql//localhost:3306/hibernatedb</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.hbm2ddl.auto">udpate</property>
<mapping class="com.chandu.app.model.UserDetails"/>
</session-factory>
Main class:
public class HibernateTest {
public static void main(String[] args) {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = getUserObject();
session.save(user);
session.getTransaction().commit();
session.clear();
}
private static UserDetails getUserObject() {
UserDetails user = new UserDetails();
user.setUserName("Test User");
return user;
}
Console:
Code Structure:
I have gone through some of the forums, but couldnt find a solution for the same.
Thanks for the help!
jdbc:mysql//localhost:3306/hibernatedb
Use a colon (:) both before and after "mysql":
jdbc:mysql://localhost:3306/hibernatedb
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 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.
I have used EclipseLink till now, but now I'm trying a Java SE project with Hibernate 4. I'm trying to do perform a NamedQuery but I get the following exception:
HibernateLog --> 18:05:03 ERROR org.hibernate.internal.SessionFactoryImpl - HHH000177: Error in named query: SubCategory.findAll
org.hibernate.hql.internal.ast.QuerySyntaxException: Subcategory is not mapped [SELECT s from Subcategory s]
This is my DBUtils class
public class DBUtils {
static final Logger logger = Logger.getLogger(DBUtils.class);
private static final ServiceRegistry serviceRegistry;
private static final SessionFactory sessionFactory;
/**
*
*/
//initialize session factory;
static {
try {
Configuration conf = new Configuration()
// mapped classes;
.addAnnotatedClass(Category.class)
.addAnnotatedClass(SubCategory.class)
.configure();
//.....
serviceRegistry = new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry();
sessionFactory = conf.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
logger.error("Initial SessionFactory creation failed");
System.err.println("." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static synchronized SessionFactory getSessionFactory() {
return sessionFactory;
}
}
And this is my 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>
<!-- Database connection settings -->
<!-- Ommitted... -->
<!-- JDBC connection pool, use Hibernate internal connection pool -->
<property name="connection.pool_size">5</property>
<!-- Defines the SQL dialect used in Hibernate application -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<!-- hibernate sql output -->
<property name="show_sql">false</property>
<property name="format_sql">false</property>
<property name="use_sql_comments">false</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.connection.useUnicode">true</property>
<property name="hibernate.connection.characterEncoding">utf8</property>
<property name="hibernate.connection.CharSet">utf8</property>
</session-factory>
</hibernate-configuration>
Finally my entities are all annotated with #Entity("tableName") annotation
What am I doing wrong?
Hibernate is case sensitive and uses the class name to map an Entity in its HQL. So
SELECT s from Subcategory s
will refer to an entity class called Subcategory. This is wrong. Use the actual class name
SELECT s from SubCategory s
as your class is named SubCategory, seen in
.addAnnotatedClass(SubCategory.class)