IntelliJ IDEA
IntelliJ IDEA – the Leading Java and Kotlin IDE, by JetBrains
Creating a Simple Jakarta Persistence Application
In this blog, we’re going to look at how to create a simple Jakarta Persistence application in IntelliJ IDEA Ultimate. Jakarta Persistence is the new name for the Java Persistence APIs also known as JPA. These APIs allow you to store, access and manage Java objects in a relational database.
This blog post covers the same material as the video with some additional tips and tricks. This provides an easy way for people to skim the content quickly if they prefer reading to watching, and to give the reader/watcher code samples and links to additional information.
Creating a new Jakarta Persistence Project
First, we’ll create a new project in IntelliJ IDEA Ultimate by clicking on the New Project button in the Welcome screen. We’ll select Java Enterprise from the left menu which allows us to take advantage of the enterprise framework support provided in IntelliJ IDEA Ultimate. In this tutorial, I’ll use the latest Long Term Supported (LTS) Java version which is Java 11. Then, I’ll select Library for my template. I won’t be using any application servers for my persistence application so I will not configure the application server field. Then, I’ll click Next.
In the next window, we’ll select the libraries required by my application. I want to use the latest available APIs so I’ll select Jakarta EE 9 from the drop down menu. Under Implementations, I will select EclipseLink. Then, I’ll click Next.
In the next window, I will set the project name to JakartaPersistenceApp
and change the group to my company name, com.jetbrains
. Then click Finish. IntelliJ IDEA will create the project and generate some files for us.
Adding the Database Dependencies
In our new project, let’s open our generated pom.xml file. You’ll notice that IntelliJ IDEA generated some dependencies needed for our application based on the frameworks selected when we created our project. In addition to these dependencies, our application will also need the dependencies for the database where we’ll be persisting our data. In this tutorial, I’ll use a light-weight database called HyperSQL. In my pom.xml file, I’ll add my HyperSQL dependency by pressing Alt+Insert for Windows/Linux or ⌘N for macOS. Then, I’ll choose Dependency. A window will popup that I’ll use to search for my HyperSQL dependency by entering hsqldb
in my search window. Under org.hsqldb
, I will select the latest version to include in my pom.xml file. Then, click Add. The following dependency will be added to the pom.xml file as a result:
<dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.5.1</version> </dependency>
When the dependency is added, I will load my maven changes by pressing on Ctrl+Shift+O on Windows/Linux or ⇧⌘I on MacOS. I can also click on the icon that appears in the top right corner of my pom.xml file. Now that our dependencies are all set, let’s start creating the files needed for our persistence application.
Creating an Employee Entity
We’ll open up our Persistence tool window by going to View -> Tool Windows -> Persistence. The Persistence tool window allows us to create a variety of resources for our persistence applications. You’ll see that IntelliJ IDEA created a persistence.xml
configuration file where we’ll configure our managed persistence classes as well as our database. In addition, a default persistence unit is created for us.
Let’s create an Entity which will represent an Employee. We can do so by right-clicking on our default persistence unit clicking New then clicking Entity.
For Create Class, we’ll enter in Employee
. For Destination Package, we’ll create a new package called entity
. Since the package currently doesn’t exist, it’ll be shown in red. Once we click OK, IntelliJ IDEA will create the new entity package along with our Employee class. Our Employee class will be created with a generated ID along with its setter and getter.
According to the Jakarta Persistence specification, an entity must have a no-arg constructor so we’ll generate it by bringing up the Generate window using Alt+Insert for Windows/Linux or ⌘N for macOS. We’ll choose Constructor from the list. Then click Select None so we can generate a constructor with no arguments. IntelliJ IDEA creates the Employee no-arg constructor.
Now let’s add a couple more variables to our Employee entity. I’ll add a String variable for the Employee’s first name called fName
(which isn’t the best variable name but we’ll be changing that later in the tutorial). We’ll also add a String variable for the Employee’s last name called lName
.
You’ll notice that the Employee Entity has some gutter icons.
The gutter icon on the Entity class declaration allows you to navigate to the Persistence Tool Window. There are also gutter icons for your entity’s persistent fields. IntelliJ IDEA will distinguish ID fields with a small key icon. You’ll notice that the ID field has two gutter icons, one for field access and one for property access.
Let’s go ahead and generate the setters and getters for my new fields. I’ll bring up the Generate menu (Alt+Insert for Windows/Linux or ⌘N for macOS) and select Getter and Setter. I’ll press Ctrl to select both variables and click OK. IntelliJ IDEA generates the getters and setters for both variables.
Here is what my Employee class looks like so far:
package entity; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @Entity public class Employee { @Id @GeneratedValue private Long id; private String fName; private String lName; public Employee() { } public void setId(Long id) { this.id = id; } public Long getId() { return id; } public String getfName() { return fName; } public void setfName(String fName) { this.fName = fName; } public String getlName() { return lName; } public void setlName(String lName) { this.lName = lName; } }
Creating the Main Class
Now that our Employee entity is complete, let’s create our Main
class where we’ll create an Employee object and persist it to a database. In the Project Window, we’ll select the java
folder and bring up the New menu by pressing Alt+Insert for Windows/Linux or ⌘N for macOS. Choose Java Class and then type in our class name, Main
.
In our new class, let’s add a main method. I’ll type in main
and press Enter, letting IntelliJ IDEA complete the declaration for me. Now, I’ll create the Employee object that we’ll persist to our database. We’ll create an Employee object then set its first and last name.
Now, the first step to persisting my employee is to create an EntityManagerFactory (you’ll notice that if you type Emf, IntelliJ IDEA will bring up the EntityManagerFactory class that we can select). IntelliJ IDEA will also suggest a variable name that you can use. We’ll create the EntityManagerFactory by calling the Persistence.createEntityManagerFactory("default")
method with default
as our persistence unit name.
Next, we’ll create the EntityManager by calling the EntityManagerFactory.createEntityManager()
method. Once we do, we can now begin a transaction by calling the EntityManager’s getTransaction().begin()
. Then, we can persist our Employee object that we created earlier by calling the EntityManager’s persist
method. Now that this is done, we can cleanup our resources. We’ll commit our transaction and close our EntityManager and EntityManagerFactory.
The final Main class should look similar to the following:
import entity.Employee; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; public class Main { public static void main(String[] args) { Employee employee = new Employee(); employee.setfName("Dalia"); employee.setlName("Abo Sheasha"); EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("default"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); entityManager.persist(employee); entityManager.getTransaction().commit(); entityManager.close(); entityManagerFactory.close(); } }
At this point, we’re almost ready to persist our data. The main step missing is setting up the database where our data will be persisted. You’ll remember earlier in the tutorial we mentioned that we’ll be using HyperSQL as our database. So, let’s go ahead and setup our database.
Setting up the HyperSQL Database
Let’s navigate to our persistence.xml
configuration file from the Persistence tool or Project window (under src/main/resources/META-INF/persistence.xml
). In the persistence.xml
file, you’ll notice that our Employee entity has already been configured as a managed persistence class in our default persistence unit. Let’s add the Jakarta Persistence properties required to configure our HyperSQL database.
You’ll see that as soon as you start typing <
, IntelliJ IDEA brings up suggestions for all the element that go into <persistence-unit>
. I’ll choose <properties>
and press Enter. Then I’ll start typing <
and select <property>
which will insert <property>
with the name
and value
attributes.
For my first property, I want to specify the HyperSQL JDBC driver. I’ll set the first property name
attribute to jakarta.persistence.jdbc.driver
and value
attribute to org.hsqldb.jdbcDriver
.
Then, I’ll add another property element to configure the database URL. I’ll set the property name
attribute to jakarta.persistence.jdbc.url
. For the value, I want my program to create an embedded HyperSQL database for me when it runs. So I will specify my URL to create an embedded database in my project’s target directory and call it myDB
. I’ll also set the shutdown property to true so that the database will close with the last connection. I can do this by specifying a value
of jdbc:hsqldb:file:target/myDB;shutdown=true
.
Next, I’ll add two property elements to configure the database user and password. For the user, I’ll set the property name
attribute to jakarta.persistence.jdbc.user
and value
attribute to user
. For the password, I’ll set the property name
attribute to jakarta.persistence.jdbc.password
and value
attribute to password
.
Finally, I’ll add another property that will result in my entity’s table being generated for me in the database. I’ll set the property name
attribute to jakarta.persistence.schema-generation.database.action
and value
attribute to create
. This property results in the Employee table getting created for me in the database. Another option is to set this property to drop-and-create
(I like to set this value when I’m in the process of creating an Entity’s definition and haven’t finalized my schema yet).
The final persistence.xml
file should look like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" version="3.0"> <persistence-unit name="default"> <class>entity.Employee</class> <properties> <property name="jakarta.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/> <property name="jakarta.persistence.jdbc.url" value="jdbc:hsqldb:file:target/myDB;shutdown=true"/> <property name="jakarta.persistence.jdbc.user" value="user"/> <property name="jakarta.persistence.jdbc.password" value="password"/> <property name="jakarta.persistence.schema-generation.database.action" value="create"/> </properties> </persistence-unit> </persistence>
Running the Jakarta Persistence Application
Now that we’ve finished configuring our database, let’s go back to our Main
class and run our application. We can run our application by pressing Ctrl+Shift+F10 for Windows/Linux or ^⇧R for macOS.
Once our application runs, a HyperSQL database will be created as well as an Employee table. Then our Employee object will be persisted to our database table. At this point, you might want to view the tables that were created for you in the database. To do that, let’s configure IntelliJ IDEA to connect to the HyperSQL database that was created by our application.
Viewing the Persisted Employee in the Database
Open the Database tool window by going to View -> Tool Windows -> Database. Click on the + button and choose Data source from URL.
Then, paste in the database URL specified in the persistence.xml
file (jdbc:hsqldb:file:target/myDB;shutdown=true
). IntelliJ IDEA will detect that it’s a HyperSQL URL. Click OK.
Let’s finish configuring the database. I’ll set the database configuration name to myDB
. For my User and Password fields, I’ll enter the user and password I set in my persistence.xml
file (user
, password
). If you have a warning about missing HyperSQL drivers, click on the Download missing driver files
.
Under the Options tab, I will enable the Auto-disconnect after setting and set it to disconnect after 3 seconds. This setting will disconnect the database in IntelliJ IDEA and release all locks allowing my application’s process to continually connect and write to the database. Then I will test my connection and make sure my configuration is valid before finally clicking OK.
In the Database Window, you will now see the myDB
database. The database contains an EMPLOYEE
table under the default PUBLIC
schema. You can also see a SEQUENCE
table which is used by EclipseLink to generate ID values. When we double-click on the EMPLOYEE
table, we see that our Employee entity is persisted into an Employee table with an ID
, FNAME
and LNAME
column. We also see the data from the Employee object we created in our Main
class.
Now that we have our database configured, let’s connect this datasource to our persistence unit by right-clicking on the default persistence unit in the Persistence tool window and clicking Assign Data Sources… then selecting our myDB
database from the drop-down menu. This step is required for the IntelliJ IDEA code completion that we’ll see in the next section.
Modifying the Application
I want to persist another Employee object so I’ll go back to my Main
class. Since my first Dalia
Employee is already persisted, I can take advantage of the code I already wrote and simply replace the first and last name with other names:
employee.setFirstName("Hermione"); employee.setLastName("Granger");
I also want to make some adjustments to my Employee object so I’ll navigate to my Employee
class. I want to rename my variables and give them better names. I’ll select the fName
variable and press Shift+F6. I’ll choose Include Accessors and rename my field from fName
to firstName
. I’ll do the same for the lName
variable and replace lName
with lastName
.
Now, let’s try to rerun our application so we can persist our second Employee.
You’ll notice that after the application runs, we get an error saying that the firstName object was not found.
This error happens because the first time the application ran, it created an Employee table using the fName
variable name as its column name. After refactoring the variable to firstName
, the application tries to persist the second Employee into the existing table using the new firstName
variable which doesn’t match the database table.
We can either drop the EMPLOYEE
table and create a new table with the new variable name or, if we have existing data in our table, and we can’t drop the table, we can add an @Column
annotation that maps the Entity’s variable to the database column. Since I don’t want to lose my existing data, I’ll add the @Column
annotation to my Entity’s variables. On the firstName
variable declaration, I’ll start typing in the @Column
annotation then select the name
attribute from the list of suggestions. Then, I will press Ctrl+Space for code completion. IntelliJ IDEA will bring up the current EMPLOYEE
table column names. I will choose the FNAME column name.
Note: the database code completion is only available after you assign your persistence unit to your data source we did in the last section.
We’ll similarly add the @Column
annotation to the lastName
variable.
@Column(name = "FNAME") private String firstName; @Column(name = "LNAME") private String lastName;
If your Employee entity is generated with property access (the @Id
is on the getId()
method instead of the id
field), place your @Column
annotations on your getFirstName()
and getLastName()
methods instead of your fields.
Now, let’s try to re-run our application.
The application runs successfully. We can verify that the second employee was persisted to the database by going to the Database view and viewing our EMPLOYEE
table.
If you’re wondering why the ID jumped from 1 to 51 between our runs, it’s because by default the JPA provider, EclipseLink, reserves 50 numbers for generated IDs so you’ll notice that every time you run your application, the generated ID will jump by 50.
In this tutorial we created a Jakarta Persistence application that persisted an Employee entity into a database. The application used for this tutorial is available on GitHub.
See also
- Jakarta Persistence (JPA) in IntelliJ IDEA
- Persistence Tool Window
- Connecting to a Database
- Creating Your First Jakarta EE Application