Hibernate AutoCommit Example in Java - java

I just started learning Hibernate, but based on the reading I have done in the manual, the below code appears to be using auto-commit as commit() is not being explicitly called. All of the examples I found here show use of commit(). Since I am just learning I wanted to get confirmation from the community that I was thinking the right way.
this.session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
session.clear();
entityReturned = (MultipleKeyTable) session.get(MultipleKeyTable.class, entityId);
session.close();
Edit
I should have mentioned that the hibernate.connection.autocommit is not defined in config and I believe that by default it is set to true.
Edit
I was wrong hibernate.connection.autocommit is set to false by default. Thanks Apostolos .

You can setup the autocommit mode at hibernate via hibernate.connection.autocommit
property
please read the configuration documentation
Based on your updated question, you are not using autocommit since you didnt specify the autocommit in your configuration. You are also making a select query, so you wont see if something happens in your db. make some changes, save them and then check again.
You need to commit your transaction in order to save the changes, or define autocommit = true at your properties.

Related

JPA commit() after persist() : Required or Not

I am working an a JPA 2.0 project, where I am saving my Entity class objects like :-
InitialContext ctx = new InitialContext();
UserTransaction userTrans = (UserTransaction)
ctx.lookup("java:comp/UserTransaction");
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_NAME);
EntityManager em = emf.createEntityManager();
User user = new User("ankit","nigam",25);
em.persist(user); // persisted in db after this executes
userTrans.commit(); // whether it is required OR not.
So whether I am using userTrans.commit() or not, my user object is getting saved in Db, after persist() executes. But some of my colleagues say, as a standard we should commit() the transaction.
What should be the approach which I follow and whats the logic behind commit() and persist(). Please throw some lights.
Is autocommit ON in your DB? If it is then that is the reason why the changes get permanently stored in your DB irrespective of whether or not you commit the transaction from your application. In production the autocommit is generally set OFF because it hampers the performance/response time of the DB, that is why developers are generally encouraged to control the commit or rollback of a transaction from their application. The link details the command to handle autocommit in db2: http://www.db2util.com/administration/options-db2-command-line-disable-autocommit/

Hibernate session factory close drops all auto generated tables

Using hibernate4
SessionFactory factory = new Configuration().configure()
.buildSessionFactory();
Session session = factory.openSession();
session.beginTransaction();
//do some task
session.getTransaction().commit();
session.close();
factory.close();
Using auto generated proprty
<property name="hibernate.hbm2ddl.auto">create-drop</property>
as you can see I am closing my session factory it drops all my tables after this code completed as I see on console. Is it the default behaviour
This is expected behavior for the create-drop mode.
See this documentation for more information.
Additionally, see this article for more exposition on the values.
That's the intention of the property create-drop.
Use create or update to keep your tables.
change hbm2dll.auto property in your hibernate mapping to "update" to keep the changes you do in the database.

Hibernate and currentSession: "Heck, I don't want these transactions!"

I substituted:
sessionFactory.openSession();
With:
sessionFactory.getCurrentSession();
And I added this configuration for Hibernate:
<property name="hibernate.current_session_context_class">thread</property>
Now I'm getting this error:
failureorg.hibernate.HibernateException: createQuery is not valid without active transaction
Why should I use beginTransaction() and so on, after I use currentTransaction? I don't want to use transactions... so, what should I change?
You used getCurrentSession, not currentTransaction. Transactions are not optional in Hibernate—you must start a transaction.
The configuration you set up resulted in a session being opened for you automatically, but not a transaction within the session.
You can, skip beginning and committing of transactions by spring integration and declaring your transaction as annotation driven

Why can I insert/update data with hibernate even when there's no transaction involved?

As we all know that in Hibernate if no transaction commit, the changes won't affect in database. But I found something weird. And the code as follows:
ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring.xml");
SessionFactory sessionFactory = (SessionFactory) ctx.getBean("sessionFactory");
Session session = sessionFactory.openSession();
Model model = new Model();
...
session.save(model);
session.flush();
session.close();
And the model was saved to database even there's no transaction, anyone can explain this?
Any comments would be appreciated! Thanks!
PS: I am using mysql.
The session.flush command saved the transaction. If it's wrong, you should use transaction.
usually hibernate needs the line session.beginTransaction(); to work. You didn't write that and your application worked, I guess your application runs in an Application server, which provides transaction management. e.g. jboss, weblogic...
However it doesn't mean that there is no transaction. Did you set auto-commit true?
btw, session.flush() and txn.commit() are different.
Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.
After session.flush(), you still can call txn.rollback() to rollback all changes.
edit
oh I saw you used spring. did you configured txnmanager in spring?
Hibernate doesn't need transactions, the most common problems in database-based applications are just easier to solve with transactions which is why usually everyone uses transactions with Hibernate. But that's mere coincidence/convention/laziness.
All Hibernate needs is a java.sql.Connection and if your container provides one even though there is no current transaction manager configured, Hibernate is fine with that.
In fact, Hibernate has no idea that there might be a transaction manager. So session.flush() will use the ApplicationContext to get a connection, generate the SQL and use JDBC to send the generated SQL code to the database.
From Hibernate's point of view, that's all that happens.
There can be several reasons why the data is committed to the database:
You forgot to turn of auto commit on the connection.
Your web container / spring config automatically wires a transaction manager that synchronizes with HTTP requests.
Your code is called form another method which is annotated with #Transactional; in this case, you inherit the existing transaction.

Reuse Hibernate session in thread

I've read somewhere that when a session is flushed or a transaction is committed, the session itself is closed by Hibernate. So, how can i reuse an Hibernate Session, in the same thread, that has been previously closed?
Thanks
I've read somewhere that when a session is flushed or a transaction is committed, the session itself is closed by Hibernate.
A flush does not close the session. However, starting from Hibernate 3.1, a commit will close the session if you configured current_session_context_class to "thread" or "jta", or if you are using a TransactionManagerLookup (mandatory JTA) and getCurrentSession().
The following code illustrates this (with current_session_context_class set to thead here):
Session session = factory.getCurrentSession();
Transaction tx = session.beginTransaction();
Product p = new Product();
session.persist(p);
session.flush();
System.out.println(session.isOpen()); // prints true
p.setName("foo");
session.merge(p);
tx.commit();
System.out.println(session.isOpen()); // prints false
See this thread and the section 2.5. Contextual sessions in the documentation for background on this.
So, how can i reuse an Hibernate Session, in the same thread, that has been previously closed?
Either use the built-in "managed" strategy (set the current_session_context_class property to managed) or use a custom CurrentSessionContext derived from ThreadLocalSessionContext and override ThreadLocalSessionContet.isAutoCloseEnabled().
Again, see the above links and also What about the extended Session pattern for long Conversations?
Wrong. The session is stays open, just a new transaction begins. The main thing is that all objects currently attached to the session STAY attached, so if you don't clear the session you have a memory leak here.

Categories

Resources