java hibernate - cannot find beginTransaction and createQuery - java

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);

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.

Do I need to close a hibernate stateless session if I provide a spring managed DB connection?

If I have a Spring Transaction managed DataSource, and use it to provide the connection to a Hibernate stateless session, do I need to close the stateless session? And if so, would it be a noop with regards to closing the DB connection and committing the DB transaction?
This is what I have now:
import java.sql.Connection;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceUtils;
...
#Autowired
private SessionFactory sessionFactory;
#Autowired
private DataSource dataSource;
public MyObj getCurrentByName(String name)
{
StatelessSession session = null;
try
{
Connection conn = DataSourceUtils.getConnection(dataSource);
session = sessionFactory.withStatelessOptions()
.connection(conn)
.openStatelessSession();
return (MyObj) session.createCriteria(MyObj.class)
.add(Restrictions.eq("isCurrent", true))
.add(Restrictions.eq("name", name))
.setComment("MyObj by name")
.uniqueResult();
}
finally
{
if (session != null)
{
session.close();
}
}
}
So again, is the session.close() going to just clean up the session object? i.e. not commit the txn nor close the DB connection?

Exception in thread "main" java.util.ServiceConfigurationError [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
This error is occuring with Hibernate 3.2 and resolved by using ServiceRegistryBuilder
This is my code:
public class HibernateTest {
public static void main(String[] args) {
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Sam");
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
}
}
Error:
Exception in thread "main" java.util.ServiceConfigurationError: org.hibernate.boot.registry.selector.StrategyRegistrationProvider: Provider org.hibernate.cache.infinispan.StrategyRegistrationProviderImpl not found
at java.util.ServiceLoader.fail(ServiceLoader.java:231)
at java.util.ServiceLoader.access$300(ServiceLoader.java:181)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:365)
at java.util.ServiceLoader$1.next(ServiceLoader.java:445)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.loadJavaServices(ClassLoaderServiceImpl.java:340)
at org.hibernate.boot.registry.selector.internal.StrategySelectorBuilder.buildSelector(StrategySelectorBuilder.java:162)
at org.hibernate.boot.registry.BootstrapServiceRegistryBuilder.build(BootstrapServiceRegistryBuilder.java:222)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:119)
This was the error while executing the hibernate framework with wrong api's.
This problem was resolved by changing my code like this:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateTest {
private static SessionFactory sessionFactory;
public static void main(String[] args) {
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Sam");
if (sessionFactory == null) {
Configuration configuration = new Configuration().configure();
ServiceRegistryBuilder registry = new ServiceRegistryBuilder();
registry.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = registry.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
}
}
This was the code.
You have different version of Hibernate. Probably 4 and above. According to guideline you should use following syntax
http://www.codejava.net/frameworks/hibernate/building-hibernate-sessionfactory-from-service-registry

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

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();

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

Categories