Hibernate sessionupdate doesn't work if not in transaction

My hibernate config:

Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
properties.put("hibernate.hbm2ddl.auto", "validate");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.id.new_generator_mappings", "false");
properties.put("hibernate.connection.autocommit", "true");
properties.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
properties.put("hibernate.connection.url", DBConnection.url);
properties.put("hibernate.connection.username", DBConnection.username);
properties.put("hibernate.connection.password", DBConnection.password);

      

Sample code:

// pattern 1
Session s = sessionFactory.openSession();
ObjectA A = s.load(ObjectA.class, pk);
A.setAttr("abc");
s.update(A);
s.close();

// pattern 2
Session s = sessionFactory.openSession();
s.beginTransaction();
ObjectA A = s.load(ObjectA.class, pk);
A.setAttr("abc");
s.update(A);
s.close();

// pattern 3
Session s = sessionFactory.openSession();
Transaction tx = s.beginTransaction();
ObjectA A = s.load(ObjectA.class, pk);
A.setAttr("abc");
s.update(A);
tx.commit();
s.close();

      

Please ignore my compilation error. I am using hibernate in a web application (without spring

) and without using a transaction, because I am using a database MySql

and it MySql

autocommit

is true, so in turn in hibernation I do it as autocommit

true. (I also use mysql-connector-java-5.1.23-bin.jar

).

Three templates, I can only get Figure 3. Now I am completely confused. I have a few questions below:

1) I can't figure out why pattern 1 doesn't work, all mine select

(via hibernate CriteriaBuilder

or load

) and insert

(via hibernate session.save

) are working, but update only doesn't work.

2) OK, then I am trying to use transaction as pattern 2, my hibernate auto-commit

is true, so my guess is that when I close the session, the transaction should be automatically committed, but it doesn't work. Why?

3) Template 3 works, why do I need a transaction manager? I want to be able to jdbc

execute every single query in every transaction (one sql in one transaction), I am not worried about performance, but here I need to enable the transaction, why?

For templates 1 and 2 I found that the update

script was not even generated (based on the hibernation log), the problem is not that the script was generated but the crash exited. Do not understand why? Please, help...


PS:

Just run some points for future reference after some trial and error:

1) Hibernate only generates sql script when called session.flush()

, but not tx.commit()

, but session.flush()

should be called in a transaction block. without a transaction, this throws an exception. Explicit flush is not needed if auto flush mode commit()

will trigger reset.

2) Hibernate operation is not equivalent to database transaction, after some attempts I found that if hibernate autocommit is false yes they are functionally equivalent and the corresponding begin transaction

script is generated via JDBC and sent to databases (just my guess). If hibernate autocommit is true, no is begin transaction

running, although we declare it in hibernate Transaction tx = s.beginTransaction()

, all queries will autosave and rollback

not work.

3) The reason for my case session.save()

(and also select

) is running without a transaction, this is a bit special because it save

has to be run to get the table id (primary key) and therefore the sql script is generated even without the flush.

4) For template 2 i am missing, autocommit does not mean autocommit upon session closed

its true value should be autocommit upon each sql reach database

. so template 2 won't work because no tx.commit

, which means there is no flush, so no sql script is generated. (whether or not the tx.commit

software is automatically called session.close

depends on the vendor implementation, some will rollback.)

Conclusion. The block of transactions is needed in sleep mode, it doesn't matter what.

+3


source to share


1 answer


I think you have a bit of confusion. The transaction (org.hibernate.transaction) is not exactly a DB transaction. Such an object is hibernated when you end your session (Session.flush) to bind the statement in a single db transaction. In other words, don't confuse a Hibernate session with a DB session, however don't put up with hibernate Sessio with a db connection. Most importantly, with specialatio, hibernate only generates sql code for what's included between hibernate transactions. This is why pattern A and B doesn't work and doesn't generate sql code. More specifically, auto-commit in template B has no effect since the sql cod is never generated. Also, in line with the highest hibernation prices, you must remember to open and close a transaction even for a simple select command. By the way,the selection should work even without a transaction, but you may have problems.

To better understand the concept, we can resume the architecture:

  • hibernate session: the container that holds your hibernate object and your db operations as Java objects, and more. hibernate transaction: a transaction object related to the hibernate session.
  • db connection: your DB connection
  • conenction pool: This is a collection of db connections.


That appen, when the session is cleared, can be resumed with the following step:

  • the connection is obtained from the connection pool
  • for every committed transaction in your session, db connection is obtained from the pool, sql commands are generated and sent to DB
  • the db connection is pushed back to the pool

this is just a small summary, but hope this help so.

+2


source







All Articles