javatalks Java Programmers Forum Java Forum программистовjavatalks.ru / 2006 - {current year} © javatalks.ru javatalks.ru Links javatalks Articles javatalks Conference Our Open Source Project
Registration
Enter
English Russian Ukrainian
×
Javatalks Articles Javatalksconference Our Open Source Project
Hibernate Tutorial
Forum/ Databases and Java/
Persistence in Java (JPA, ORM, ODB)
1 2 3
anchor 08 jul 2009 22: 31
Starover
Messages:9282
The concept of ORM
Hibernate.
General information and recommended literature
Downloads
The main configuration file (hibernate.cfg.xml)
The simplest class
HibernateUtil
Running the first example
Hibernate and its cache.
get() vs. load()
Logging In Hibernate
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Updated:18 Dec 2012 12: 02
anchor 08 jul 2009 22:32
Starover
Messages:9282
1.
The concept of ORM
ORM(Object/Relational Mapping) - this is a way to save objects to a relational database.
In other words, ORM frees us from working with SQL and allows us to focus on OOP.
The basis of the ORM is a configuration file that describes how the object will be written to the database.
If everything is just as primitive with primitive fields: a string field is written to a column with the varchar type, an integer field is written to an int, then everything is more interesting with relationships between objects.
For example, there are classes Book and Author, configuration files have been created for both, which describe their fields.
But the Book, among other things, has a link to the Author.
In this case, the tables in the database will be linked by a foreign key, which is also described in one of the configuration files.
Note: ORM can be described not only in configuration files, annotations are also used, but for ease of understanding, they will not be discussed yet.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Changed:08 jul 2009 23: 10
anchor 08 jul 2009 23:04
Starover
Messages:9282
2.
Hibernate.
General information
Hibernate is one of the most popular ORM frameworks today.
Of course, the fact that we got rid of SQL is a plus, but we should not forget about the negative sides, the main of which is performance.
It goes without saying that working with the database through well written SQL code will be more productive than using Hibernate.
However, SQL still needs to be able to write correctly, while Hibernate creates optimized queries.
Developers also spend a lot of time writing queries and stored procedures, while working with Hibernate speeds up the development process.
One of the attractive aspects of Hibernate is that it supports dialects to all popular DBMSs.
Our applications are also becoming DBMS independent, because the only thing that will have to be changed if we want to switch to another DBMS is the dialect in the Hibernate configuration.
For the functioning of Hibernate, you need: 1. The main configuration file, which describes the parameters of the connection to the database.
2. Description of the relationship between the class and the table.
Includes a relationship between a class field and a table column.
It also describes the relationship of classes with each other.
Hibernate is a very complex framework, a lot of information has been written about it, if it is interesting to study it thoroughly, you can do this: Start Hibernate In Action the book is mediocre, but it will be useful for beginners.
POJOs In Action is an excellent book for understanding how to work with ORMs like Hibernate, JPA, JDO.
The Hibernate Reference will give a more complete picture about Hibernate
Java Persistence with Hibernate - a more detailed book about Hibernate, a must read for a real understanding of Hibernate.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Changed:05 Jun 2012 10: 38
anchor 09 jul 2009 13: 36
Starover
Messages:9282
3.
Downloads
Let's start downloading Hibernate 3.2.6.ga.
In the future, of course, it will be possible to download a newer version, but for now this is the most relevant.
Many people (including me) were burned by the fact that they were pumping a complete package of Hibernate from the official site.
But, as it turned out, the libraries that come in this bundle have incompatible versions, which usually leads to a ClassNotFoundException when the application is launched.
So, here are the necessary libraries that can be downloaded from the central maven repository:
hibernate 3.2.6.ga.jar mysql connector java 5.1.6.jar log4j 1.2.9.jar dom4j 1.6.1.jar slf4j api 1.5.2.jar slf4j simple 1.5.2.jar jta 1.1.jar icu4j 2.6.1.jar commons logging 1.0.4.jar commons collections 3.1.jar cglib nodep 2.1_3.jar
All of them will need to be connected to future Hibernate projects.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Changed:11 jul 2009 19: 12
anchor 10 jul 2009 12: 35
Starover
Messages:9282
4.
Main configuration file(hibernate.cfg.xml)
As mentioned above, Hibernate requires a main configuration file to function.
Here it is (the library database is specified here, so to use this config after that, create a database with this name):<?
xml version= '1.0' encoding= 'utf 8'?
> <!
DOCTYPE hibernate configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD/ / EN" "http://hibernate.sourceforge.net/hibernate configuration 3.0. dtd"> <hibernate configuration> <session factory> <property name="hibernate.connection.driver class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url"> jdbc:mysql://localhost/library </property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.connection.autocommit">true</property> <property name="show sql">true</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- Mapping files --> <mapping resource="Book.hbm.xml"/> </session factory> </hibernate configuration>
hibernate.
connection.driver class specify the show sql driver class - if set to true, SQL queries will be output to the console, which are hidden behind the Hibernate code dialect the dialect of communicating with the database hibernate.
hbm2ddl.
auto a property that specifies what to do with the database schema during initialization.
It can take the following values: update checks the database schema with the existing class configurations, if we have made any changes, they are automatically entered into the database.
At the same time, the data that was entered into the database will not change - even if we decided to delete some fields from the table, they will all remain create - every time the application is launched, the database schema will be created again.
All the data that was entered earlier will be deleted by create drop every time the application is launched, the database schema will be created again, and when it is completed, it will be deleted.
All data that was entered during the operation of the application will be deleted upon completion of the validate application - during initialization, a check will be made whether the class configurations and the database schema correspond.
If we have made a change to the configuration of some class, and the schema in the database has not been changed, an exception will be thrown
Next is the class description section.
Here we specify the files that are responsible for configuring each of the classes.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Changed:05 Jun 2012 10: 28
anchor 11 jul 2009 19: 29
Starover
Messages:9282
5.
The simplest class
Let's write a simple class with three fields: a Long type identifier, a string field - the name of the book and the number of pages represented by an integer type.
Please note that the class must have a default constructor.
Since we have not declared any, it will be so.
package ru.javatalks.faq.persistence.hibernate.bookstore;
/** * 10.07.2009 23:43:14 * * @author ctapobep */ public class Book { private Long id; private String title; private int pageCount;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public int getPageCount() { return pageCount; }
public void setPageCount(int pageCount) { this.pageCount = pageCount; } }
Now we will describe its configuration file.
All these files must have a name ClassName.hbm.xml.
That is, in our case it is Book.hbm.xml:<?
xml version= "1.0"?
> <!
DOCTYPE hibernate mapping PUBLIC "- //Hibernate/Hibernate Mapping DTD 3.0/ / EN" "http://hibernate.sourceforge.net/hibernate mapping 3.0.dtd"> <hibernate mapping package="en.javatalks.faq.persistence.hibernate.bookstore"> <class name="Book" table="books"> <id name="id" column="id" unsaved value="null"> <generator class="native"/> </id> <property name="title" type="string" column="title" length="255"/> <property name="pageCount"/> </class> </hibernate mapping> By points:<property name= "title" type= "string" column= "title" length= " 255 " /> Here we have established that the title field will be created in the table with the type varchar (or varchar2 in Oracle), with a length of 255.
If we had not set the length, Hibernate would have determined it itself, and it would have been the maximum allowable length of this type for this database.
Since we have MySQL, the field length would have been 255.
As for the field type, if you do not specify it, Hibernate will determine it itself, but only for primitives and wrapper classes(Integer, Double, etc.).
<property name="pageCount"/> As you can see, we did not specify either the type or the name of the column here - Hibernate will set everything independently.
<id name="id" column="id" unsaved value="null"> <generator class="native"/> </id> The ID field is a prerequisite for the operation of Hibernate.
Its type can be either a string or a number, the main condition is uniqueness.
The unsaved value attribute defines how Hibernate will distinguish an already saved object(persistent) from an already untouched one (unsaved).
In this case, if the object ID turns out to be null, it means that it has not yet been saved to the database.
By the way, here we can observe a win of the Long type before long: the latter cannot be null, it will have an unsaved value of 0, which is not so obvious.
generator is an identifier generator.
Its class will be responsible for how the unique identifier will be generated.
In this case, the native class is installed, which allows you to use the DATABASE generator itself.
You can read more about identifiers and generators here.
<class name= "Book" table= "books" > The tag that describes the class.
Here we have specified the name of the class and the table that will correspond to it.
More details.
<hibernate mapping package= "ru. javatalks. faq.persistence.hibernate.bookstore"> The main tag of this configuration file.
Here we have specified only the package in which our class is stored.
If we mentioned more classes here without specifying their packages, then this one would be used.
I would like to note that if we had a class in a child package relative to the one described above, then we would have to refer to this class by specifying the absolute name of the package, and not the relative one.
That is, let's say we have a package ru.
javatalks.
faq.persistence.hibernate.bookstore.derived, then we would refer to the class in it ru.javatalks.faq.persistence.hibernate.bookstore.DerivedClass.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Updated:20 Nov 2009 16: 46
anchor 26 jul 2009 21:46
Starover
Messages:9282
6.
HibernateUtil
Let's add a utility class that will load Hibernate and provide access to it: HibernateUtil.java package ru.javatalks.faq.persistence.hibernate.util;
import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration;
/** * 26.07.2009 20:27:43 * * @author ctapobep */ public class HibernateUtil { private static final SessionFactory sessionFactory;
static { try { //creates the session factory from hibernate.cfg.xml sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (ExceptionInInitializerError ex) { System.err.println("Initial SessionFactory creation failed: " + ex); throw new ExceptionInInitializerError(ex); } }
/** * Gets hiberante session factory that was initialized at application startup.
* * @return hibernate session factory */ public static SessionFactory getSessionFactory() { return sessionFactory; } }
This code creates a SessionFactory object - a factory that is used to create these are the Hibernate sessions that we will actually work with.
A session factory is a thread safe global object that needs to be initialized only once.
A very important place here is played by the Configuration object and its configure () method.
If you initialize the session factory in the way described above, then the file hibernate.cfg.xml it will be searched in the classpath.
We can also explicitly specify the location of this file by using an overloaded version of the configure(String) method.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Updated:18 Oct 2009 22: 28
anchor 02 sep 2009 18:53
Starover
Messages:9282
7.
Run the first example
Well, the theory is probably enough.
We need to finally launch something :) Let's save, extract, modify and delete the record from the database.
This is a typical CRUD operation(create, read, update, delete).
import org.hibernate.Session; import ru.javatalks.faq.persistence.hibernate.bookstore.Book; import ru.javatalks.faq.persistence.hibernate.util.HibernateUtil;
public class Main { public static void main(String[] args) { Session session = HibernateUtil.getSessionFactory().openSession(); Book book = new Book(); book.
setPageCount(520); book.setTitle ("Tales of Round Table"); session.
save (book);//we saved the book, our id was generated and immediately filled with book = (Book) session.get(Book.class, book.getId()); book.setPageCount(430); session.save(book); session.delete(book); session.flush(); session.close(); } } You can set up breakpoints and monitor how the content of the books table changes with each line.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Changed:02 Sep 2009 19: 27
anchor 28 feb 2011 14: 39
Starover
Messages:9282
Hibernate and its caches
Hibernate has the following cache levels: Session level (1 level cache) - works only between opening and closing a session.
For example, if you selected an object and then want to select it again , it will be taken from the cache.
After closing the session, the entire cache will be cleared.
It is when the session is closed, since the session can be used for several transactions, then these several transactions can use the session level cache together.
However, as a rule, when working with Hibernate, the session lives a single transaction.
Process level (2 level cache, SessionFactory cache) - data from all sessions is cached here.
It should be noted, however, that if we are talking about fetch="join", then Hibernate will never search for child objects in the cache.
For example, from Authors a join a.books of the Author will be selected from the cache, and the books will be selected from the database.
If the Books are loaded with an additional request (that is, fetch= "select"), then the objects will be taken from the cache (if they are there, of course).
In general, this cache works using some cache regions (=spaces), when each entity is assigned to some cache block.
For example, so: books space will include the Book entity.
authors space will include both books and their authors, because for example, when updating authors, you need to update books as well.
This is a fairly abstract example, just to explain what it is
These regions are needed in order to determine which operations need to update/kill the cache.
Configuration of these regions is performed in hbm.xml in the file, as well as in the configuration of the cache provider itself.
Query cache is an extension of the 2nd level cache.
If you activate it, then when executing the request, all the IDs of the selected objects will be saved in the cache.
When the request is executed again, it will not be executed in the database, just take all the IDs and the corresponding objects will be selected from the cache of the 2nd level.
Such a cache is useful only for read only data or data that is very rarely changed, because this cache is completely cleared if at least one change occurs in the table affected by the query.
You can make sure that the query cache is enabled by default, for this you need to set the Hibernate: hibernate.cache.use query cache to true in the configuration
Hibernate cache & Native SQL Queries: Hib allows you to execute regular SQL queries, where you can write a query of any flexibility.
The problem here is that since we are in charge of which tables and columns to change, the Hib cannot track which cache region this applies to, and because the most important thing for us is data integrity, the Hib cleans the entire second level cache during each such request.
This happens because our query can change some row in the table, but in the cache this "row" will remain with the same value and when working with this cache, we will get outdated data.
However, since we ourselves know at the time of writing the request which regions this can hook, we can tell the Kiba which regions to clean, so that it does not kill everything under the clean.
This is done as follows: SqlQuery sql = session.
CreateSQLQuery ("update author ..."); sql.
addSynchronizedEntityClass(Author.class); SqlQuery.
executeUpdate();
In this case, the regions assigned to the Author will be cleared, but only they.
You can also specify other parameters: sql.
addSynchronizedEntityName ("en. javatalks.bookstore.Author"); sqlQuery.addSynchronizedQuerySpace("author");
Well, the last method, if you describe the request in hbm.xml in the file, it will look like this: <sql query name= "updateAuthor" > <synchronize table= "author" / > update author set... </sql query> If you know that no data updates will occur or that this will not affect the quality of the caches in any way, you can specify: sql.
addSynchronizedQuerySpace("");
An empty string will mean in this case that no caches will be cleared.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Changed:17 May 2014 00: 48
anchor 13 apr 2012 16: 16
Starover
Messages:9282
The difference between get () & load()
Both methods return an object by ID, but they do it quite differently.
In this case, we are considering the usual situation when we do not have lazy="false" set for the class and bytecode enhancement is not used.
To begin with, it is worth mentioning that Hibernate can return both a proxy (a wrapper over an object created in runtime) and the object itself.
If the proxy has returned, then it can be in an initialized state, when all primitive and non lazy fields are circled, as well as in a state when it has only an ID.
Total: session.get(Book.class, BookID) - will access the database (well, or find an object in the cache) and return the initialized proxy.
If the object is not found, null is returned.
When we access the lazy fields, they are loaded.
session.
load(Book.class, BookID) - an uninitialized proxy will return, there will be no access to the database at all.
It will just be a proxy that received only the information that we passed to the method.
The proxy is initialized only when we access its fields, and then select will be performed.
And in this case, if the object is not in the database or cache, an exception will be thrown.
This option can be much more efficient, but we need to know for sure that objects with such IDs exist.
For example, in the following code there will be no select: Book book = session.
load(Book.class, 24L); Author author = session.load(Author.class, 12L); book.setAuthor(author); session.save(book);
Only insert will be performed.
You should also understand that when you pull the connection of an object with another object (book.getUser ()) - the proxy is returned.
And even when you pull getId (), the proxy will return and no select will be performed (unless you have disabled the proxy or use bytecode enhancement, otherwise at least an object with primitives will be loaded).
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
anchor 25 may 2012 16: 01
Starover
Messages:9282
Logging in Hibernate Article moved to: JavaTalks Articles
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
Updated:18 Dec 2012 12: 02
anchor 03 jun 2012 13: 25
pashalost
Messages:34
1) It is not clear how to configure log4j ("And add this to log4j:" does not bring much clarity) 2) It would not be superfluous to explain which classpath is meant when saving hibernate.cfg.xml (you could just say the src folder, and immediately a bunch of people would stop posting their ridiculous mistakes.) 3) mysql is not the best name for a test database of an example for beginners, try to guess why ?
anchor 05 jun 2012 10: 33
Starover
Messages:9282
1.
This is not a tutorial on log4j, I would not like to overload the posts with information.
In addition, this is a fairly deep and far from mandatory configuration of the Hiba.
2. What is SRC?
Over the past couple of years, I have hardly seen any projects where src is the root of classpath.
If you are interested in finding out what it is, it is described here, you can also search the web for more detailed information if this is not enough.
3. I changed it, thank you.
PS: Hib is a very complex framework, it makes sense to start getting acquainted more closely with core java, here are books for beginners.
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
anchor 05 jun 2012 10:54
usik
Messages:190
Old Believer, you would have done something similar with EntityManager. (Preferably an approach with anotations)
, then everyone would be happy.
anchor 05 jun 2012 11: 58
Starover
Messages:9282
I prefer not to work with JPA, but this is a separate story:)
JTalks Open Source | Test Data Management | Karma - Evaluate Risks in JIRA
1 2 3
Moderators:No They are currently viewing this topic:No
2006 - 2015 © javatalks.ru Powered by JCommun e 3.3.3000.ac531c0 byjtalks.org Design withTwitter Bootstrap
