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.
Related
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.
I was trying to figure out how hibernate works and few things are there I want to how they works and I wanted to know if I understood correctly.
EntityManagerFactory emf = Persistence.createEntityManagerFactory();
The above does following things
Creates entitymanager factory instance.
EntityManagerFactory stores the mapping for all the entity classes.
Its the provider of entity manager instances.
what else above line does?
EntityManager em = emf.createEntityManager()
createa an entitymanager.
EntityManager is responsible for managing lifecycle of managed objects.
what else above line do? does it create a session with database?
em.getTransaction().begin();
Does above lines creates a database session?
is session and transaction and session are java side things or database side things?
what transaction and session means ?
em.getTransaction().commit();
I feel that this line does all the work of creating transaction and saving the data to the database. am I correct?
em.close();
this line closes the database session.
emf.close();
all the mapping present in the factory are lost and eligible for GC?
Am I correct with my understandings?
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
I have a little of confusion about JDBC connection, transactions and their integration in EJB, JTA, Hibernate environment. My doubts are:
when we use #Resource DataSource ds; ... ds.getConnection() , are we working in the same transaction used by the managed bean? Should we close the connection, statement, resultset?
what about session.doWork? Are we in the same transaction? What about closing statement and result set?
aggressive release mode in Hibernate means that connections are closed after each statement. Does it mean that transaction is committed too? (I don't think this is true, but I can't understand how Hibernate works here)
There are a few things you need to figure out. First thing you need to identify what is your unit of work.
The session-per-request pattern is one of the most used and unless you have specific needs stick with that.
If you are using Hibernate you don't use statements and result sets directly. Hibernate will do that for you. what you need to close is the hibernate session
What you use is a SessionFactory and a Session object. The session pretty much represents your unit of work. Inside the hibernate session you get your objects, you change them and save them back.
The session per request pattern opens a session when a request is received and closes it when the response is sent back.
In a container managed EJB session bean a transaction is available and the datasource you (or hibernate) use in such a container is automatically handled by a JTA TransactionManager.
Now because Hibernate is smart it can automatically bind the "current" Session to the current JTA transaction.
This enables an easy implementation of the session-per-request strategy with the getCurrentSession() method on your SessionFactory:
try {
UserTransaction tx = (UserTransaction)new InitialContext()
.lookup("java:comp/UserTransaction");
tx.begin();
// Do some work
factory.getCurrentSession().load(...);
factory.getCurrentSession().persist(...);
tx.commit();
}
catch (RuntimeException e) {
tx.rollback();
throw e; // or display error message
}
So to answer your questions:
If you are using Hibernate with JTA in a container you'd be better off using a JPA EntityManager or maybe spring hibernate template.
Here are some references:
http://community.jboss.org/wiki/sessionsandtransactions#Transaction_demarcation_with_JTA
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/orm/hibernate3/HibernateTemplate.html
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.