Get invalid without active transaction - hibernation 5

I keep getting this error even if I started the transaction manually.

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); transaction = session.getTransaction(); if(!transaction.isActive()) { transaction = session.beginTransaction(); } accessToken = session.get(OAuthAccessToken.class, token); 

hibernate.cfg.xml

 <property name="hibernate.connection.autoReconnect">true</property> <!-- Use the C3P0 connection pool. --> <property name="hibernate.c3p0.min_size">5</property> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.timeout">300</property> <property name="hibernate.c3p0.max_statements">50</property> <property name="hibernate.c3p0.idle_test_period">3000</property> <!-- Disable second-level cache. --> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <property name="cache.use_query_cache">false</property> <property name="cache.use_minimal_puts">false</property> <property name="max_fetch_depth">3</property> <!-- Bind the getCurrentSession() method to the thread. --> <property name="current_session_context_class">thread</property> <property name="hibernate.jdbc.batch_size">30</property> 

HibernateUtils

 public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { // Create the SessionFactory from hibernate.cfg.xml Configuration config = new Configuration().configure(); config.setProperty("hibernate.show_sql", String.valueOf(ConfigManager.getInstance().getBoolean(Consts.CONFIG_DB_SHOW_SQL, false))); config.setProperty("hibernate.format_sql", String.valueOf(ConfigManager.getInstance().getBoolean(Consts.CONFIG_DB_FORMAT_SQL, false))); config.setProperty("hibernate.dialect", ConfigManager.getInstance().getString(Consts.CONFIG_DB_DIALECT, "org.hibernate.dialect.MySQLDialect")); config.setProperty("hibernate.connection.driver_class", ConfigManager.getInstance().getString(Consts.CONFIG_DB_DRIVER_CLASS, "com.mysql.jdbc.Driver")); config.setProperty("hibernate.connection.url", ConfigManager.getInstance().getString(Consts.CONFIG_DB_URL, "jdbc:mysql://localhost/photometo")); config.setProperty("hibernate.connection.useUnicode", "true"); config.setProperty("hibernate.connection.characterEncoding", "UTF-8"); config.setProperty("hibernate.connection.username", ConfigManager.getInstance().getString(Consts.CONFIG_DB_USERNAME, "root")); config.setProperty("hibernate.connection.password", ConfigManager.getInstance().getString(Consts.CONFIG_DB_PASSWORD, "")); config.setProperty("hibernate.hbm2ddl.auto", ConfigManager.getInstance().getString(Consts.CONFIG_DB_HBMDDL_AUTO, "update")); sessionFactory = config.buildSessionFactory(); } catch (Throwable ex) { throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } } 

I noticed that this begins after a while. If I restart the tomcat application or the re-deployed application, the problem will disappear.

+6
source share
1 answer

You never started a transaction, and you cannot get a transaction different. This is why you get an error message:

  Session session = HibernateUtil.getSessionFactory().getCurrentSession(); transaction = session.getTransaction(); // Here is the error! You can't get an active transaction, becasue there isn't even started if(!transaction.isActive()) // transaction.isActive() is usually for closing a transction in the end { transaction = session.beginTransaction(); // You are starting the transaction! } accessToken = session.get(OAuthAccessToken.class, token); 

You cannot receive an active transaction because it was not even started. Change the code:

  // Non-managed environment idiom with getCurrentSession() try { factory.getCurrentSession().beginTransaction(); // do some work ... factory.getCurrentSession().getTransaction().commit(); } catch (RuntimeException e) { factory.getCurrentSession().getTransaction().rollback(); throw e; // or display error message } 

The correct reason for starting transactions in an unmanaged environment is the Hibernation Documentation :

 // Non-managed environment idiom with getCurrentSession() try { factory.getCurrentSession().beginTransaction(); // do some work ... factory.getCurrentSession().getTransaction().commit(); } catch (RuntimeException e) { factory.getCurrentSession().getTransaction().rollback(); throw e; // or display error message } // Non-managed environment idiom with getCurrentSession() try { factory.getCurrentSession().beginTransaction(); // do some work ... factory.getCurrentSession().getTransaction().commit(); } catch (RuntimeException e) { factory.getCurrentSession().getTransaction().rollback(); throw e; // or display error message } 

Following the documentation of getTransaction () , your current session did not start the transaction.

 getTransaction() Get the Transaction instance associated with this session. 

And here is why starting a transaction 11.2 Demarcation of database transactions :

A database or system, transaction boundaries are always needed. no connection to the database can occur outside of the transaction database (this seems to confuse many developers who are used to automatic commit mode). Always use clear transaction boundaries, even for read-only operations.

And a long transaction is bad for the database, because a lot of locks are generated in your database, Session and transaction

To reduce the lock on the database, the database transaction should be as short as possible. Long database transactions will prevent your application from scaling to a highly competitive load. It is not recommended to open a database transaction during user time until the operation block is completed.

+2
source

Source: https://habr.com/ru/post/1014446/


All Articles