このコンテンツは選択した言語では利用できません。
2.3.8. Loading and Storing Objects
We are now ready to start doing some real worjk with Hibernate. Let's start by writing an
EventManager
class with a main()
method:
In
createAndStoreEvent()
we created a new Event
object and handed it over to Hibernate. At that point, Hibernate takes care of the SQL and executes an INSERT
on the database.
A org.hibernate.Session is designed to represent a single unit of work (a single atmoic piece of work to be performed). For now we will keep things simple and assume a one-to-one granularity between a Hibernate org.hibernate.Session and a database transaction. To shield our code from the actual underlying transaction system we use the Hibernate
org.hibernate.Transaction
API. In this particular case we are using JDBC-based transactional semantics, but it could also run with JTA.
What does
sessionFactory.getCurrentSession()
do? First, you can call it as many times and anywhere you like once you get hold of your org.hibernate.SessionFactory
. The getCurrentSession()
method always returns the "current" unit of work. Remember that we switched the configuration option for this mechanism to "thread" in our src/main/resources/hibernate.cfg.xml
? Due to that setting, the context of a current unit of work is bound to the current Java thread that executes the application.
Important
Hibernate offers three methods of current session tracking. The "thread" based method is not intended for production use; it is merely useful for prototyping and tutorials such as this one. Current session tracking is discussed in more detail later on.
A org.hibernate.Session begins when the first call to
getCurrentSession()
is made for the current thread. It is then bound by Hibernate to the current thread. When the transaction ends, either through commit or rollback, Hibernate automatically unbinds the org.hibernate.Session from the thread and closes it for you. If you call getCurrentSession()
again, you get a new org.hibernate.Session and can start a new unit of work.
Related to the unit of work scope, should the Hibernate org.hibernate.Session be used to execute one or several database operations? The above example uses one org.hibernate.Session for one operation. However this is pure coincidence; the example is just not complex enough to show any other approach. The scope of a Hibernate org.hibernate.Session is flexible but you should never design your application to use a new Hibernate org.hibernate.Session for every database operation. Even though it is used in the following examples, consider session-per-operation an anti-pattern. A real web application is shown later in the tutorial which will help illustrate this.
See the "Transactions and Concurrency" Chapter for more information about transaction handling and demarcation. The previous example also skipped any error handling and rollback.
To run this, we will make use of the Maven exec plugin to call our class with the necessary classpath setup:
mvn exec:java -Dexec.mainClass="org.hibernate.tutorial.EventManager" -Dexec.args="store"
Note
You may need to perform
mvn compile
first.
You should see Hibernate starting up and, depending on your configuration, lots of log output. Towards the end, the following line will be displayed:
[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)
[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)
This is the
INSERT
executed by Hibernate.
To list stored events an option is added to the main method:
A new
listEvents() method is also added
:
Here, we are using a Hibernate Query Language (HQL) query to load all existing
Event
objects from the database. Hibernate will generate the appropriate SQL, send it to the database and populate Event
objects with the data. You can create more complex queries with HQL. See the Hibernate Query Language chapter for further information.
Now we can call our new functionality, again using the Maven exec plugin:
mvn exec:java -Dexec.mainClass="org.hibernate.tutorial.EventManager" -Dexec.args="list"