3.1 Linking Hibernate and Databases

We learned how to connect Hibernate to our application using Maven, and how to map tables to classes using annotations. And now the next question arises - how do we read objects from the database or save them there?

Not so fast. First of all, you need to deal with three more things:

  • Configuring a database connection
  • Setting up Hibernate
  • Working with EntityManager

Hibernate completely hides the work with the database from your application, but in order to avoid any excesses, it must be configured correctly. You can’t skip this stage - otherwise how will Hibernate know which database to save objects to?

Hibernate can be configured and given database information in three ways

  • Use Properties file
  • Use hibernate.cfg.xml file
  • Use Configuration bean methods

And although I like the last one the most, you will definitely encounter all three, so we will analyze all three here.

3.2 Authorization in the database

Let's start with the most important - database connections. To do this, you will need to provide data so that Hibernate can log in to the desired database.

Properties File Configuration
hibernate.properties
hibernate.dialect= org.hibernate.dialect.Oracle9Dialect
hibernate.connection.driver_class= oracle.jdbc.driver.OracleDriver 
hibernate.connection.url= jdbc:oracle:thin:@localhost:1521:supershop
hibernate.connection.username=root
hibernate.connection.password=secret
hibernate.show_sql=true
hibernate.hbm2ddl=update

The same settings can be set in the form of an xml file:

XML Based Configuration
hibernate.cfg.xml

<hibernate-configuration>	
	<session-factory>	
        	
    	<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>  	
    	<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 	
    	<property name="connection.url">jdbc:oracle:thin:@localhost:1521:supershop</property>  	
    	<property name="connection.username">root</property>  	
    	<property name="connection.password">secret</property>
    	<property name="hibernate.show_sql ">true</property>        
    	<property name="hbm2ddl.auto">update</property> 	
     	
	</session-factory>	
</hibernate-configuration> 

In both examples, we see the same settings with the same values. It's just that the first example represents them as a properties file , and the second one as an xml file .

These settings are divided into three groups:

  1. Specify the type of DBMS
    • Specify the dialect (DBMS type), for example, Oracle 9.0
    • Specify the name of the JDBC driver for working with this DBMS
  2. Specify data for authorization in the database
    • database url
    • username
    • password
  3. Configuring the Hibernate Engine
    • hibernate.show_sql- Hibernate will duplicate in the console all requests that it executes
    • hbm2ddl.auto- Hibernate will change the database structure if necessary

There is a third way of setting configuration - through bins. It is usually used in conjunction with Spring, so we'll look at it when we learn SpringFramework.

3.3 Get the SessionFactory

The next step is to get the SessionFactory object. There are several ways to do this:

The first way is to use the hibernate.properties file .

To do this, you just need to write the following code:

SessionFactory sessionFactory = new Configuration().buildSessionFactory();

If the hibernate.properties file is not found in the current project directory, an exception will be thrown.

The second way is configuration using hibernate.cfg.xml .

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

If you write such code, then the hibernate.cfg.xml. If no such file is found, the method buildSessionFactory()will throw an exception.

The third way is to set the configuration file manually .

Sometimes during the development process it becomes necessary to switch to a test base or change some other settings for working with the base, for this you can set the configuration file manually:

SessionFactory sessionFactory = new Configuration().configure("hibernate-dev.cfg.xml").buildSessionFactory();

Method four - we use a custom hibernate.properties file:

ClassLoader classLoader = Thread.currentThread().getClassLoader();

Properties properties = new Properties();
properties.load(classLoader.getResourceAsStream("hibernate-dev.properties"));

SessionFactory sessionFactory = new Configuration()
            .addProperties(properties)
            .buildSessionFactory();

And finally, you can simply sew all the necessary parameters directly into the code:

Properties properties = new Properties();
properties.put(Environment.DRIVER, "com.mysql.jdbc.Driver");
properties.put(Environment.URL, "jdbc:mysql://localhost:3306/supershop");
properties.put(Environment.USER, "root");
properties.put(Environment.PASS, "password");

SessionFactory sessionFactory = new Configuration()
            .setProperties(properties)
            .buildSessionFactory();

3.4 Specify where to look for Entity classes

But that is not all. When we configure a SessionFactory object in Hibernate, this SessionFactory checks that all the required tables with the required column types exist in the database.

And in order for the SessionFactory to be able to do this, it needs to be passed a list of entity classes that it needs to map to the database.

There are three ways to pass a list of entity classes:

Method one. In hibernate.cfg.xmladd a line like:

<mapping class="class-qualified-name" />

Example:

<mapping class="com.codegym.data.User" />
<mapping class="com.codegym.data.Employee" />
<mapping class="com.codegym.data.Task" />

Method two. Call the method on the ConfigurationaddAnnotatedClass() object . Example:

SessionFactory sessionFactory = new Configuration()
   	.configure()
   	.addAnnotatedClass(com.codegym.data.User.class)
   	.buildSessionFactory();

If there are many classes, then you can add them in whole packages:

SessionFactory sessionFactory = new Configuration()
   	.configure()
   	.addPackage("com.codegym.data")
   	.buildSessionFactory();

3.5 Final example

Now that we've learned how to configure the SessionFactory object, let's write the code that will use it.

It will consist of three methods:

  1. Configuring Hibernate
  2. Method that gets all employees from the database
  3. Method that saves a new employee to the database

This code template would look something like this:

class EmployeeManager {
    private SessionFactory sessionFactory;

    public void class init() {
    	this.sessionFactory = new Configuration()
        	.configure()
        	.buildSessionFactory();
   }

   public List<Employee> getAllEmployes() {
         try (Session session = sessionFactory.openSession()) {
  	          Query<Employee> query = session.createQuery("from Employee", Employee.class);
    	        return query.list();
         }
   }

   public void addEmployee(Employee employee ) {
     	try (Session session = sessionFactory.openSession()) {
            Transaction transaction = session.beginTransaction();
       	    session.save(employee);
            transaction.commit();
     	}
   }
}

Before executing a query to the database, you need to create a separate session. If the requests are related, then they can be executed in the same session. If the requests are unrelated (and several minutes can pass between them), then they need to make their own sessions.

If you want to read data from the database or execute a complex query, you must first create a Query object and use it to execute your query.

Also, each query to the database is executed in its own transaction. You need to open it, perform the necessary operations, and then close (commit).

In the following lectures, we will analyze in more detail how this all works.

undefined
1
Task
Module 4. Working with databases, level 9, lesson 2
Locked
task0903
task0903
undefined
1
Task
Module 4. Working with databases, level 9, lesson 2
Locked
All names
task0904