How can I create a Hibernate session without hiberante.cfg.xml file? - java

This is my first time using Hiberante.
I am trying to create a Hibernate session within my application using the following:
Session session = HiberanteUtil.getSessionFactory().openSession();
It gives me this error:
org.hibernate.HibernateException: /hibernate.cfg.xml not found
However I do not have a hibernate.cfg.xml file within my project.
How can I create a session without having this file?

import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.concretepage.persistence.User;
public class HibernateUtil {
private static final SessionFactory concreteSessionFactory;
static {
try {
Properties prop= new Properties();
prop.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate");
prop.setProperty("hibernate.connection.username", "root");
prop.setProperty("hibernate.connection.password", "");
prop.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
concreteSessionFactory = new AnnotationConfiguration()
.addPackage("com.concretepage.persistence")
.addProperties(prop)
.addAnnotatedClass(User.class)
.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession()
throws HibernateException {
return concreteSessionFactory.openSession();
}
public static void main(String... args){
Session session=getSession();
session.beginTransaction();
User user=(User)session.get(User.class, new Integer(1));
System.out.println(user.getName());
session.close();
}
}

The simples way to configure Hibernate 4 or Hibernate 5
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Hibernate reads a configuration from hibernate.cfg.xml and hibernate.properties.
You shouldn't call configure(), if you don't want to read hibernate.cfg.xml. With adding an annotated class
SessionFactory sessionFactory = new Configuration()
.addAnnotatedClass(User.class).buildSessionFactory();

Related

Custom ConfigSource for Quarkus

I'm trying now to configure custom ConfigSource in my Quarkus App. Like in many other manuals i'm created my own DatabaseSourceConfig and implements org.eclipse.microprofile.config.spi.ConfigSource interface.I registered my ConfigSource in:
/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
There is my ConfigSource:
public class DatabaseConfigSource implements ConfigSource {
private DataSource dataSource;
public DatabaseConfigSource() {
try {
dataSource = (DataSource) new InitialContext().lookup("openejb:Resource/config-source-database");
} catch (final NamingException e) {
throw new IllegalStateException(e);
}
}
#Override
public Map<String, String> getProperties() {
// Implementing Method
}
#Override
public String getValue(final String propertyName) {
// Implementing Method
}
#Override
public String getName() {
return DatabaseConfigSource.class.getSimpleName();
}
}
But this not working for Quarkus because of JNDI name. I need to use CDI. I was trying to use something like this:
#Inject
#io.quarkus.agroal.DataSource("my_connection")
AgroalDataSource usersDataSource;
and declare this connection in application.properties but it didn't help me. I'm getting all the time NULL Exception.
Maybe someone have ideas, how can i get DB connection there without to use JNDI namespace?
You can obtain the data source via
AgroalDataSource dataSource = Arc.container()
.instance(AgroalDataSource.class, new DataSource.DataSourceLiteral("my_connection"))
.get();
You'll need to do this somewhere else than the constructor though, I think, because the ConfigSource instance is created before CDI is fully booted. You can cache the obtained data source instance then to avoid executing this multiple times.
I found some answer myself, maybe it will be useful also for other ppl.
Like #Janmartiška said, CDI booted later, than ConfigSource, that's why i don't see any way to inject my connection via CDI.
I was created some HibernateUtil Class:
package org.myproject.config;
import java.util.Properties;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.myproject.entities.ConfigurationsEntity;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static SessionFactory buildSessionFactory() {
try {
Properties props = new Properties();
props.setProperty("hibernate.connection.url", "jdbc:mysql://[db-host]:[db-port]/db_name");
props.setProperty("hibernate.connection.driver_class", "com.mysql.cj.jdbc.Driver");
props.setProperty("hibernate.connection.username", "username");
props.setProperty("hibernate.connection.password", "password");
props.setProperty("hibernate.current_session_context_class", "thread");
props.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
Configuration configuration = new Configuration();
configuration.addProperties(props);
configuration.addAnnotatedClass(ConfigurationsEntity.class);
System.out.println("Hibernate Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate serviceRegistry created");
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
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);
}
}
public static SessionFactory getSessionFactory() {
if(sessionFactory == null) sessionFactory = buildSessionFactory();
return sessionFactory;
}
}
than i used it in my SourceConfig:
package org.myproject.config;
import io.quarkus.runtime.annotations.RegisterForReflection;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.myproject.entities.ConfigurationsEntity;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
#RegisterForReflection
public class DatabaseSourceConfig implements ConfigSource {
public SessionFactory sessionFactory;
public Session currentSession;
public DatabaseSourceConfig() {
sessionFactory = HibernateUtil.getSessionFactory();
this.checkFactoryConnection();
}
public void checkFactoryConnection() {
if (currentSession == null || (currentSession != null && !currentSession.isOpen())) {
try {
currentSession = sessionFactory.getCurrentSession();
} catch (NullPointerException e) {
currentSession = sessionFactory.openSession();
}
}
}
#Override
public Map<String, String> getProperties() {
// Implementing Method
}
#Override
public String getValue(String propertyName) {
this.checkFactoryConnection();
ConfigurationsEntity conf = new ConfigurationsEntity();
currentSession.beginTransaction();
try {
Query query = currentSession.createNamedQuery("Configuration.selectOne", ConfigurationsEntity.class);
query.setParameter("name", propertyName);
conf = (ConfigurationsEntity) query.getSingleResult();
currentSession.getTransaction().commit();
} catch (Exception ex) {
currentSession.getTransaction().rollback();
}
return conf.getValue();
}
#Override
public String getName() {
return DatabaseSourceConfig.class.getSimpleName();
}
}
Now i can use my ConfigSource in other classes like:
#Inject
#ConfigProperty(name = "[property-name-like-in-db]")
public String someProperty;
After my further research it was found that ConfigSource has no access to CDi and application.properties. That is why there is nothing left but to establish a connection to the database in the manner described above.
However, I did a little editing of the example. I cached properties from the database and created a #ApplicationScoped Bean that looks into the database once every 5 minutes to see whether one of properties "updated_at" has a timestamp later than others from Bean loaded properties.
However, I have to say that according to Quarkus and Apache developers - this violates “immutable deployment” and is not planned to change the application settings during runtime. So it depends on you whether you write it in the app or not.

java hibernate - cannot find beginTransaction and createQuery

I got a problem with the two hibernate methods mentioned in the title, beginTransaction() and createQuery(). Java gives me the cannot find symbol error
This is how I start my session
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
public static SessionFactory createSessionFactory() {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
}
and this is how I use the two methods
SessionFactory session = HibernateUtil.createSessionFactory();
Transaction tx = null;
Users user = null;
try {
tx = session.beginTransaction();
tx.begin();
Query query = session.createQuery("FROM USERS WHERE USERNAME='"+userId+"'");
user = (Users)query.uniqueResult();
tx.commit();
}
I'm fairly unfamiliar with hibernate and I don't understand why this is happening. I set up my xml config file properly. Netbeans supposedly added all the necessary libraries and I still get the error
You have to change this line :
SessionFactory session = HibernateUtil.createSessionFactory();
to
Session session = HibernateUtil.createSessionFactory().openSession();
Because SessionFactory interface does not implement the SharedSessionContract interface which include both
getTransaction()
createQuery(String string)
methods like Sessioninterface does.
And it is good practice to use parameter binding instead of using string concatenation.
Query query = session.createQuery("FROM USERS WHERE USERNAME= :userName")
.setParameter("userName",userId);

Hibernate SessionFactory - correct way to create factory, session and handle resources

For teaching purposes, I am creating Hibernate console applications. Since Hibernate is quite complex, I want to be sure that I handle the initialization, exceptions, and shutdown correctly. The examples that I have found are not optimal in my opinion. (Official Hibernate examples use test cases.)
I have HibernateUtil for initialization and shutdown of Hibernate.
package com.zetcode.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateUtil {
private SessionFactory sessionFactory;
public HibernateUtil() {
createSessionFactory();
}
private void createSessionFactory() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure() // configures settings from hibernate.cfg.xml
.build();
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
// try {
// sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
// } catch (Exception e) {
// The registry would be destroyed by the SessionFactory, //but we had trouble building the SessionFactory
// so destroy it manually.
// StandardServiceRegistryBuilder.destroy(registry);
}
}
public SessionFactory getSessionFactory() {
// if (sessionFactory == null) {
// createSessionFactory();
// }
return sessionFactory;
}
public void shutdown() {
getSessionFactory().close();
}
}
Here is a console Java application:
package com.zetcode.main;
import com.zetcode.bean.Continent;
import com.zetcode.bean.Country;
import com.zetcode.util.HibernateUtil;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
public class Application {
public static void main(String[] args) {
HibernateUtil hutil = new HibernateUtil();
SessionFactory sessionFactory = hutil.getSessionFactory();
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
Continent europe = new Continent("Europe");
Continent asia = new Continent("Asia");
Country svk = new Country("Slovakia");
Country hun = new Country("Hungary");
Set<Country> europeCountries = new HashSet<>();
europeCountries.add(svk);
europeCountries.add(hun);
europe.setCountries(europeCountries);
Country chi = new Country("China");
Country afg = new Country("Afganistan");
Set<Country> asiaCountries = new HashSet<>();
asiaCountries.add(chi);
asiaCountries.add(afg);
asia.setCountries(asiaCountries);
session.save(europe);
session.save(asia);
// moved
//session.getTransaction().commit();
Query query = session.createQuery("SELECT c FROM Country c");
List<Country> countries = query.getResultList();
countries.stream().forEach((x) -> System.out.println(x));
Query query2 = session.createQuery("SELECT c FROM Continent c");
List<Continent> continents = query2.getResultList();
continents.stream().forEach((x) -> System.out.println(x));
session.getTransaction().commit();
} finally {
hutil.shutdown();
}
}
}
The example works OK. But, is this code correct? I am using Hibernate 5.2.
Edit I have incorporated the suggestions from the comments into the code.

compiler error in hibernate 5.0.1

I am learning hibernate, I have added all the required jars, but still am getting a compiler error saying
Configuration.configure cannot be resolved to a type.
My jar list:
Anyone have idea how to resolve this?
package org.ramya.hibernate;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
import org.ramya.dto.UserDetails;
public class HibernateTest {
public static void main (String args[])
{
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("First user");
SessionFactory sessionFactory = new Configuration.configure().buildSessionFactory();
Session session = sessionFactory.openSession();
}
}
You missed the parentheses () when instantiating the Configuration object.
It should be:
new Configuration().configure()
Try to use This,
SessionFactory sf;
ServiceRegistry sr;
Configuration cfg=new Configuration().configure();
sr=new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
sf=cfg.buildSessionFactory(sr);
Instead of ,
SessionFactory sessionFactory = new Configuration.configure().buildSessionFactory();
Since "buildSessionFactory()" has been deprecated over hibernate 3.5
And try to use latest version of hibernate as much as possible.
Please check this link for Details:-
Deprecated Buildsessionfactory

Why I'm getting this error when I run my file?

I have this class:
TestHibernate1.java
package hibernatetest2;
import java.util.Date;
import org.hibernate.*;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class TestHibernate1 {
public static void main(String args[]) throws Exception {
Configuration configuration = new Configuration();
configuration.addClass(Personnes.class);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory1 = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory1.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Personnes personne = new Personnes("nom6", "prenom6", new Date());
session.save(personne);
session.flush() ;
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
session.close();
}
}
The error is :
Exception in thread "main" org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:104)
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:71)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:209)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:89)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:178)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1885)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1843)
at hibernatetest2.TestHibernate1.main(TestHibernate1.java:20)
Looking at the code it seems the hibernate configuration file is missing. The right steps are (assuming hibernate version >= 4.3.5)
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration
.buildSessionFactory(serviceRegistry);
Verify if you are following the right steps.

Categories