Hibernate: How to Launch
Launching Hibernate Framework can be a tricky task. This page provides you with multiple ways to do it, it can be useful to you if you're trying to run your first application with Hibernate and it just crashes, or if you need Proof-of-Concept or an archetype of project with specific configuration. Every sample application on this page maintains a simple goal - to read something from database, which is a proof of Hibernate up and running.
All projects on this page use H2 database.
Just pick a desired configuration option, create specified files and you're good to go.
H2 Database
[edit | edit source]Ignore this section if you're going to use Maven. Otherwise, download H2 zip, find \h2\bin\h2-$version.jar
file in it and proceed to one of the Standalone non-Maven sections on this page.
If you want to know how to use H2 database without writing an application, this section shows how to do it.
Installation
[edit | edit source]- Download H2 zip here: https://www.h2database.com/html/download.html
- Extract it to
~\AppData\Local\Programs
- Create a shortcut for
\h2\bin\h2.bat
- Place it to
~\AppData\Roaming\Microsoft\Windows\Start Menu
. Now you can easily start H2 from Start menu.
Usage
[edit | edit source]- Start H2 .bat or shortcut, web page will open with
Generic H2 (Embedded)
preset active; - Use JDBC url
jdbc:h2:mem:test
for in-memory orjdbc:h2:~/test
for local storage based db;- If local storage is used,
~/test.mv.db
file will be created and will stay there until you’ll delete it; ~/.h2.server.properties
file will be created either way;
- If local storage is used,
- Press Connect to start server and use database;
- In CMD window press CTRL+C several times to stop server.
- You don't have to run/stop H2 server manually if it's library is in classpath of your application.
Standalone
[edit | edit source]You can launch Hibernate in offline desktop application. Maybe it is a CLI app, or maybe it uses GUI frameworks like Swing or JavaFX, it doesn't matter - you can bootstrap Hibernate into it. This section shows how to do it.
Also Hibernate itself can be configured with persistence.xml, hibernate.properties or hibernate.cfg.xml file. So, we will cover every of this configuration options.
Without Maven
[edit | edit source]persistence.xml
[edit | edit source]This a proof of concept, it is recommended to use Maven.
- Choose a 6.0.0.CR2 version here: https://sourceforge.net/projects/hibernate/files/hibernate-orm/; - Since then Hibernate release bundle download is no longer provided, so this is the latest Hibernate version you can download as a bundle;
- Download
hibernate-release-6.0.0.CR2.zip
- Extract it’s
.\required
internal directory. - Into
.\required\
directory copy ah2-2.2.220.jar
file as well, it is in the same directory ash2.bat
file from above section. It contains H2 JDBC driver.
- Create
.\META-INF\persistence.xml
file: - Create
.\example\entity\Person.java
class: - Create
.\example\Start.java
class: - Examine file structure of a project:
- Compile and run it from Powershell:
--%
is needed to prevent Powershell from interpreting arguments tojava
andjavac
executables.
<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="only-unit" >
<properties>
<property name="jakarta.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="jakarta.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="jakarta.persistence.jdbc.user" value="sa" />
<property name="jakarta.persistence.jdbc.password" value="" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
package example.entity;
import jakarta.persistence.*;
// import lombok.Data;
@Entity
//@Data
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
// add Lombok to classpath, uncomment annotation and you can remove all this:
public Person() {}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return String.format("Person[%s %s]", id, name);
}
}
package example;
import jakarta.persistence.*;
import example.entity.*;
public class Start {
public static void main(String[] args) {
var emf = Persistence.createEntityManagerFactory("only-unit");
var em = emf.createEntityManager();
em.getTransaction().begin();
var person = new Person();
person.setName("Вася Петечкин");
em.persist(person);
em.getTransaction().commit();
listAll(em, Person.class);
var pupkin = em.find(Person.class, 1);
pupkin.setName("Петя Васечкин");
listAll(em, Person.class);
em.close();
emf.close();
}
public static void listAll(EntityManager em, Class entity) {
String entityName = entity.getSimpleName();
String queryString = String.format("SELECT e FROM %s e", entityName);
Query query = em.createQuery(queryString);
var resultList = query.getResultList();
System.out.printf("All records(%s):%n", resultList.size());
for (Object obj : resultList) {
System.out.println(obj);
}
}
}
.\example\Start.java .\example\entity\Person.java .\META-INF\persistence.xml .\required\antlr4-runtime-4.9.1.jar .\required\byte-buddy-1.12.7.jar .\required\classmate-1.5.1.jar .\required\h2-2.2.220.jar .\required\hibernate-commons-annotations-6.0.0.CR1.jar .\required\hibernate-core-6.0.0.CR2.jar .\required\istack-commons-runtime-4.0.1.jar .\required\jakarta.activation-2.0.1.jar .\required\jakarta.activation-api-2.0.1.jar .\required\jakarta.inject-api-2.0.0.jar .\required\jakarta.persistence-api-3.0.0.jar .\required\jakarta.transaction-api-2.0.0.jar .\required\jakarta.xml.bind-api-3.0.1.jar .\required\jandex-2.4.2.Final.jar .\required\jaxb-core-3.0.2.jar .\required\jaxb-runtime-3.0.2.jar .\required\jboss-logging-3.4.3.Final.jar .\required\txw2-3.0.2.jar
javac --% -cp .;required\*;.\classes -d classes example\entity\*.java example\*.java java --% -cp .;required\*;.\classes example.Start
hibernate.properties
[edit | edit source]- Create
Person
andStart
classes as in the previous section; - Create
.\hibernate.properties
:
hibernate.connection.driver_class org.h2.Driver
hibernate.connection.username sa
hibernate.connection.password
hibernate.connection.url jdbc:h2:mem:test
hibernate.hbm2ddl.auto create
- Replace
main()
method with this:
import org.hibernate.cfg.Configuration;
public static void main(String[] args) {
var configuration = new Configuration().addAnnotatedClass(Person.class);
var sessionFactory = configuration.buildSessionFactory();
var em = sessionFactory.openSession();
em.getTransaction().begin();
var person = new Person();
person.setName("Вася Петечкин");
em.persist(person);
em.getTransaction().commit();
listAll(em, Person.class);
var pupkin = em.find(Person.class, 1);
pupkin.setName("Петя Васечкин");
listAll(em, Person.class);
em.close();
}
- Compile and run it as in previous section.
hibernate.properties
is more concise than persistence.xml
, but now you must manually list all your annotated classes while creating Configuration.
hibernate.cfg.xml
[edit | edit source]- Create
Person
andStart
classes as in the previous section; - Create
.\hibernate.cfg.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:mem:test</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="hbm2ddl.auto">create</property>
<!-- use <mapping> or new Configuration().addAnnotatedClass(Person.class) -->
<mapping class="example.entity.Person" />
</session-factory>
</hibernate-configuration>
- Use this
main()
method:
public static void main(String[] args) {
// var configuration = new Configuration().addAnnotatedClass(Person.class).configure();
var configuration = new Configuration().configure();
var sessionFactory = configuration.buildSessionFactory();
var em = sessionFactory.openSession();
em.getTransaction().begin();
var person = new Person();
person.setName("Вася Петечкин");
em.persist(person);
em.getTransaction().commit();
listAll(em, Person.class);
var pupkin = em.find(Person.class, 1);
pupkin.setName("Петя Васечкин");
listAll(em, Person.class);
em.close();
}
- Compile and run it as in previous section. Usage of
hibernate.cfg.xml
is considered to be legacy and is not recommended for new projects.
Open in VSCode
[edit | edit source]It's simple to run a maven project in IDE, but if you'll want to run one of above combinations, here is what you need to do:
- Open project directory through
File -> Open Folder...
; - In
Explorer -> Java Projects -> Referenced Libraries
press+
sign and choose all.jar
files from.\required\
directory; - Now you can run this project through
Ctrl+F5
. InRun -> Open Configurations
you will find new run configuration:
{
"type": "java",
"name": "Start",
"request": "launch",
"mainClass": "example.Start",
"projectName": "example2023_44420544",
"classPaths": [
"required/*.jar",
"classes"
]
}
With Maven
[edit | edit source]Add Maven to existing project
[edit | edit source]Use any of the above non-maven combinations of java classes and configuration files, but also:
- Instead of placing
.jar
files into.\required
directory, create this.\pom.xml
: - Place all your .java files with package-defined directories into
.\src\main\java\
. - If there is a configuration
.xml
or.properties
file in your project, move it into.\src\main\resources\
. If this file by convention should itself be located in some kind of a directory, like/META-INF/
, move it with it's parent directory, so new location will be:.\src\main\resources\META-INF\persistence.xml
. - Examine project file structure:
.\pom.xml .\src\main\java\example\Start.java .\src\main\java\example\entity\Person.java .\src\main\resources\META-INF\persistence.xml
- Run your application with
mvn clean compile exec:java
command. - If you will need to run this goal in VSCode, add following plugin section after
<dependency>
tag, otherwise you may be not able to choose exec:java goal:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>hibertinymav</artifactId>
<version>0.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<exec.mainClass>example.Start</exec.mainClass>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core -->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.2.6.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Maven Encoding Issue
[edit | edit source]You may encounter your application fails to output some unicode characters to console under Windows platform when you run it with Maven, even though when you execute your app with VSCode internal functionality or manually with java
in CMD, characters are displayed properly. To fix this issue add this method to your main class and call it from main()
:
public static void changeConsoleEncodingIfNeeded() {
var utf8 = java.nio.charset.Charset.forName("UTF-8");
var ibm866 = java.nio.charset.Charset.forName("IBM866");
if (System.console().charset().equals(ibm866) &&
System.out.charset().equals(utf8)) {
System.out.println("System.out encoding is going to change. Before: АБВ");
System.setOut(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out), true, ibm866));
System.out.println("After: АБВ");
}
}
Spring Standalone
[edit | edit source]You can write a standalone application which uses Spring's Inversion of Control and Dependency Injection capabilities but doesn't use MVC web module.
- Create
.\pom.xml
: - Create
.\src\main\java\myapp\App.java
: - Create
.\src\main\java\myapp\model\Person.java
: - Create
.\src\main\resources\META-INF\persistence.xml
: - Create
.\src\main\java\myapp\ApplicationConfig.java
: - Create
.\src\main\java\myapp\Printer.java
: - Run your app with
mvn clean compile exec:java
. Basic read/write operations will be performed.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>hiberspringtiny</artifactId>
<version>0.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<exec.mainClass>myapp.App</exec.mainClass>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core -->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.2.6.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>6.0.10</version>
</dependency>
</dependencies>
</project>
package myapp;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {
public static void main(String[] args) {
changeConsoleEncodingIfNeeded();
System.out.println("Hello Привет");
var ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class);
// var emf = ctx.getBean(EntityManagerFactory.class);
// System.out.println(emf);
ctx.getBean(Printer.class).doPrint();
ctx.close();
}
public static void changeConsoleEncodingIfNeeded() { // you can remove this method
var utf8 = java.nio.charset.Charset.forName("UTF-8");
var ibm866 = java.nio.charset.Charset.forName("IBM866");
if (System.console().charset().equals(ibm866) &&
System.out.charset().equals(utf8)) {
System.out.println("System.out encoding is going to change. Before: АБВ");
System.setOut(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out), true, ibm866));
System.out.println("After: АБВ");
}
}
}
package myapp.model;
import jakarta.persistence.*;
// import lombok.Data;
@Entity
//@Data
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
// add Lombok to classpath, uncomment annotation and you can remove all this:
public Person() {}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return String.format("Person[%s %s]", id, name);
}
}
<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="only-unit" >
<properties>
<property name="jakarta.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="jakarta.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="jakarta.persistence.jdbc.user" value="sa" />
<property name="jakarta.persistence.jdbc.password" value="" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
package myapp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import jakarta.persistence.EntityManagerFactory;
@Configuration
@ComponentScan
@EnableTransactionManagement
public class ApplicationConfig {
@Bean
public LocalEntityManagerFactoryBean myEmf() {
LocalEntityManagerFactoryBean emf = new LocalEntityManagerFactoryBean();
emf.setPersistenceUnitName("only-unit");
return emf;
}
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
}
package myapp;
import org.springframework.stereotype.Component;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import jakarta.transaction.Transactional;
import myapp.model.Person;
@Component
@Transactional
public class Printer {
@PersistenceContext
private EntityManager em;
public void doPrint() {
System.out.println("EntityManager: "+em);
listAll(em,Person.class);
createNewPerson(em);
listAll(em,Person.class);
}
@Transactional
public void createNewPerson(EntityManager em) {
var person = new Person();
person.setName("Вася Петечкин");
em.persist(person);
}
public static void listAll(EntityManager em, Class entity) {
String entityName = entity.getSimpleName();
String queryString = String.format("SELECT e FROM %s e", entityName);
Query query = em.createQuery(queryString);
var resultList = query.getResultList();
System.out.printf("All records(%s):%n", resultList.size());
for (Object obj : resultList) {
System.out.println(obj);
}
}
}
Spring Boot Standalone
[edit | edit source]You can write a standalone application with Spring Boot. It provides you Inversion of Control and Dependency Injection capabilities but doesn't use MVC web module.
- Create
.\pom.xml
: - Create
.\src\main\resources\application.properties
: - Create
.\src\main\java\myapp\DemoApplication.java
: - Create
.\src\main\java\myapp\model\Person.java
: - Create
.\src\main\java\myapp\Printer.java
: - Run your app with
mvn clean compile spring-boot:run
. Basic read/write operations will be performed.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</project>
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
package myapp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Autowired
Printer printer;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
printer.doPrint();
}
}
package myapp.model;
import jakarta.persistence.*;
import lombok.Data;
@Entity
@Data
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
package myapp;
import org.springframework.stereotype.Component;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import jakarta.transaction.Transactional;
import myapp.model.Person;
@Component
@Transactional
public class Printer {
@PersistenceContext
private EntityManager em;
public void doPrint() {
System.out.println("EntityManager: "+em);
listAll(em,Person.class);
createNewPerson(em);
listAll(em,Person.class);
}
@Transactional
public void createNewPerson(EntityManager em) {
var person = new Person();
person.setName("Вася Петечкин");
em.persist(person);
}
public static void listAll(EntityManager em, Class entity) {
String entityName = entity.getSimpleName();
String queryString = String.format("SELECT e FROM %s e", entityName);
Query query = em.createQuery(queryString);
var resultList = query.getResultList();
System.out.printf("All records(%s):%n", resultList.size());
for (Object obj : resultList) {
System.out.println(obj);
}
}
}
Spring Web
[edit | edit source]Projects in this category are web applications built with Spring Framework.
Spring Boot Rest
[edit | edit source]- Create
.\pom.xml
: - Create
.\src\main\java\myapp\Application.java
: - Create
.\src\main\resources\application.properties
: - Create
.\src\main\java\myapp\model\Person.java
: - Create
.\src\main\java\myapp\rest\PersonController.java
: - Create
.\src\main\java\myapp\dao\PersonDao.java
: - Run your application:
mvn clean spring-boot:run
- Create new person by accessing REST endpoint with CURL or Powershell:
- Note how you'll need to explicitly state encoding if using Powershell.
- Get a list of all persons by accessing REST endpoint with CURL or Powershell (or open this link in a browser):
- You will see output:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>springboot-tiny</artifactId>
<version>0.0.1</version>
<name>First Spring Boot Example</name>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.1</version>
</parent>
<properties>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package myapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class,args);
}
}
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
package myapp.model;
import jakarta.persistence.*;
import lombok.Data;
@Entity
@Data
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
package myapp.rest;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import myapp.dao.PersonDao;
import myapp.model.Person;
@RestController
@RequestMapping("/person")
public class PersonController {
@Autowired
PersonDao personDao;
@PostMapping("/new")
public Person create(@RequestBody Person person) {
person.setId(null);
return personDao.create(person);
}
@GetMapping("/all")
public List<Person> findAll() {
return personDao.findAll();
}
}
package myapp.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import myapp.model.Person;
@Repository
public class PersonDao {
@PersistenceContext
private EntityManager em;
@Transactional
public Person create(Person person) {
em.persist(person);
return person;
}
public List<Person> findAll() {
String queryString = "SELECT p FROM Person p";
var query = em.createQuery(queryString, Person.class);
var resultList = query.getResultList();
return resultList;
}
}
curl.exe -X POST -H "Content-Type: application/json" -d '{"name":"Вася Петечкин"}' http://localhost:8080/person/new Invoke-WebRequest -Uri "http://localhost:8080/person/new" -Method POST -Body '{"name":"Вася Петечкин"}' -ContentType "application/json; charset=UTF-8"
curl.exe -X GET http://localhost:8080/person/all Invoke-WebRequest -Uri "http://localhost:8080/person/all" -Method GET | select -Expand Content
[{"id":1,"name":"Вася Петечкин"},{"id":2,"name":"Петя Васечкин"}]
Spring MVC XML-config Rest
[edit | edit source]Spring Framework can be used without Spring Boot and with XML-configuration. This project uses REST endpoint to read/write data with Hibernate.
- Create
.\pom.xml
: - Create
.\src\main\webapp\WEB-INF\web.xml
: - Create
.\src\main\webapp\WEB-INF\dispatcher-servlet.xml
: - Create
.\src\main\java\myapp\model\Person.java
: - Create
.\src\main\java\myapp\rest\PersonResource.java
: - Create
.\src\main\java\myapp\dao\PersonDao.java
: - Launch server:
mvn clean jetty:run
: - Get all people from database, add new one and get all once again:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>SpringTinyWeb</artifactId>
<version>0.1</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<spring.version>6.0.11</spring.version>
<jetty-maven-plugin.version>11.0.12</jetty-maven-plugin.version>
<hibernate-core.version>6.1.5.Final</hibernate-core.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>6.0.11</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate-core.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
<context:component-scan base-package="myapp" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean id="jacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<!--<property name="prettyPrint" value="true" />-->
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- src: https://stackoverflow.com/questions/36420880/what-is-enabletransactionmanagement-xml-equivalent-in-spring-4 -->
<tx:annotation-driven transaction-manager="txManager" />
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:dataSource;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false" />
<property name="username" value="user" />
<property name="password" value="1234" />
<!-- <property name="connectionInitSqls" value="#{T(java.nio.file.Files).readString(T(org.springframework.util.ResourceUtils).getFile('classpath:schema.sql'))}"/> -->
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="myapp"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=create-drop
hibernate.hbm2ddl.import_files=data.sql
</value>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
package myapp.model;
import jakarta.persistence.*;
// import lombok.Data;
@Entity
// @Data
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
// add Lombok to classpath, uncomment annotation and you can remove all this:
public Person() {}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return String.format("Person[%s %s]", id, name);
}
}
package myapp.rest;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import myapp.dao.PersonDao;
import myapp.model.Person;
@RestController
@RequestMapping("/person")
public class PersonResource {
@Autowired
PersonDao personDao;
@PostMapping("/new")
public Person create(@RequestBody Person person) {
person.setId(null);
return personDao.create(person);
}
@GetMapping("/all")
public List<Person> findAll() {
return personDao.findAll();
}
}
package myapp.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import myapp.model.Person;
@Repository
public class PersonDao {
@PersistenceContext
private EntityManager em;
@Transactional
public Person create(Person person) {
em.persist(person);
return person;
}
public List<Person> findAll() {
String queryString = "SELECT p FROM Person p";
var query = em.createQuery(queryString, Person.class);
var resultList = query.getResultList();
return resultList;
}
}
curl.exe -X GET http://localhost:8080/person/all
curl.exe -X POST -H "Content-Type: application/json" -d '{"name":"Вася Петечкин"}' http://localhost:8080/person/new
curl.exe -X GET http://localhost:8080/person/all
You will see read/write operations work as expected.
Spring Java-config Rest
[edit | edit source]- Create
.\pom.xml
: - Create
.\src\main\java\myapp\config\WebInit.java
: - Create
.\src\main\java\myapp\config\WebConfig.java
: - Create
.\src\main\java\myapp\model\Person.java
: - Create
.\src\main\java\myapp\rest\PersonResource.java
: - Create
.\src\main\java\myapp\dao\PersonDao.java
: - Launch web application and perform read/write operations through Rest endpoint:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>SpringMvcJavaConfig</artifactId>
<version>0.1</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<spring.version>6.0.3</spring.version>
<jetty-maven-plugin.version>11.0.12</jetty-maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.2.6.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
</dependencies>
<build>
<finalName>myapp</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
package myapp.config;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletRegistration;
public class WebInit implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
var context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("myapp.config");
container.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = container
.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
package myapp.config;
import java.util.List;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"myapp"})
@EnableTransactionManagement
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
var messageConverter = new MappingJackson2HttpMessageConverter();
// messageConverter.setDefaultCharset(Charset.forName("UTF-8")); //doesn't help anyway
messageConverters.add(messageConverter);
}
@Bean
public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
var sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setPackagesToScan("myapp.model");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public PlatformTransactionManager hibernateTransactionManager(SessionFactory sessionFactory) {
var transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
// .addScript("classpath:schema.sql")
// .addScript("classpath:data.sql")
.build();
}
private Properties hibernateProperties() {
// set hibernate properties
Properties props = new Properties();
props.setProperty("hibernate.hbm2ddl.auto", "create");
// props.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
return props;
}
}
package myapp.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
package myapp.rest;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import myapp.dao.PersonDao;
import myapp.model.Person;
@RestController
@RequestMapping("/person")
public class PersonResource {
@Autowired
PersonDao personDao;
@PostMapping("/new")
public Person create(@RequestBody Person person) {
person.setId(null);
return personDao.create(person);
}
@GetMapping("/all")
public List<Person> findAll() {
return personDao.findAll();
}
}
package myapp.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import myapp.model.Person;
@Repository
public class PersonDao {
@PersistenceContext
private EntityManager em;
@Transactional
public Person create(Person person) {
em.persist(person);
return person;
}
public List<Person> findAll() {
String queryString = "SELECT p FROM Person p";
var query = em.createQuery(queryString, Person.class);
var resultList = query.getResultList();
return resultList;
}
}
mvn clean jetty:run
curl.exe -X GET http://localhost:8080/person/all
curl.exe -X POST -H "Content-Type: application/json" -d '{"name":"Вася Петечкин"}' http://localhost:8080/person/new
Jakarta EE
[edit | edit source]Glassfish MySQL Rest
[edit | edit source]Prerequisites: standalone MySQL server.
This project differs from other sample applications on this page: instead of using embedded database, it needs separate MySQL server instance up and running. If you don't have standalone MySQL server installed, you wouldn't be able to launch this application, otherwise follow these instructions:
- Create
.\pom.xml
: - Create
.\src\main\java\myapp\model\Person.java
: - Create
.\src\main\java\myapp\rest\DemoApplication.java
: - Create
.\src\main\java\myapp\rest\PersonResource.java
: - Create
.\src\main\resources\META-INF\persistence.xml
: - Create
.\src\main\java\myapp\dao\PersonDao.java
: - Create
.\src\main\webapp\WEB-INF\glassfish-resources.xml
: - Start MySQL server, start embedded Glassfish with your webapp deployed:
- Access REST endpoint to perform read/write operations:
- To stop Glassfish, send stop-domain command via web-request, after that press Ctrl+C in appropriate terminal window.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>jakartaee-hello-world</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>jakartaee-hello-world</name>
<description>
asadmin start-domain --verbose
mysqld --console
mvn clean package
asadmin deploy --force target\myapp.war
curl.exe -X GET http://localhost:8080/myapp/rest/person/all/
curl.exe -X POST -H "Content-Type: application/json" -d '{"name":"Вася Петечкин"}' http://localhost:8080/myapp/rest/person/new
</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.report.sourceEncoding>UTF-8</project.report.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
<jakartaee-api.version>10.0.0</jakartaee-api.version>
<compiler-plugin.version>3.11.0</compiler-plugin.version>
<war-plugin.version>3.3.2</war-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>${jakartaee-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core -->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.2.6.Final</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
<build>
<!-- This bad boi becomes a parl of url and .war filename: -->
<finalName>myapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
package myapp.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
package myapp.rest;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;
@ApplicationPath("/rest/*")
public class DemoApplication extends Application {
}
package myapp.rest;
import java.util.List;
import jakarta.inject.Inject;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import myapp.dao.PersonDao;
import myapp.model.Person;
@Path("person")
public class PersonResource {
@Inject
PersonDao personDao;
@GET
@Path("all")
@Produces({ MediaType.APPLICATION_JSON })
public List<Person> findAll() {
var list = personDao.findAll();
return list;
}
@POST
@Path("new")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes(MediaType.APPLICATION_JSON)
public Person create(Person person) {
person.setId(null);
System.out.println(person);
personDao.create(person);
return person;
}
}
<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="only-unit"
transaction-type="JTA" >
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:app/jdbc/embeddedDS</jta-data-source>
<properties>
<property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />
</properties>
</persistence-unit>
</persistence>
package myapp.dao;
import java.util.List;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import myapp.model.Person;
@ApplicationScoped
public class PersonDao {
@PersistenceContext(unitName = "only-unit")
private EntityManager em;
@Transactional
public Person create(Person person) {
em.persist(person);
return person;
}
public List<Person> findAll() {
String queryString = "SELECT p FROM Person p";
var query = em.createQuery(queryString, Person.class);
var resultList = query.getResultList();
return resultList;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool
datasource-classname="com.mysql.cj.jdbc.MysqlDataSource"
name="embeddedConnPool"
res-type="javax.sql.DataSource">
<property name="URL" value="jdbc:mysql://localhost:3306/mydb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" />
<property name="User" value="root" />
<property name="Password" value="qwerty" />
</jdbc-connection-pool>
<jdbc-resource jndi-name="java:app/jdbc/embeddedDS" pool-name="embeddedConnPool" enabled="true" />
</resources>
mysqld --console
mvn clean package org.codehaus.cargo:cargo-maven3-plugin:run -Dcargo.maven.containerId=glassfish7x
curl.exe -X GET http://localhost:8080/myapp/rest/person/all/
curl.exe -X POST -H "Content-Type: application/json" -d '{"name":"Вася Петечкин"}' http://localhost:8080/myapp/rest/person/new
curl.exe -X GET http://localhost:4848/__asadmin/stop-domain -u admin:adminadmin
Glassfish H2-Embedded Rest
[edit | edit source]- Create
.\pom.xml
: - Create
.\src\main\java\myapp\dao\PersonDao.java
: - Create
.\src\main\java\myapp\model\Person.java
: - Create
.\src\main\java\myapp\rest\DemoApplication.java
: - Create
.\src\main\java\myapp\rest\PersonResource.java
: - Create
.\src\main\resources\META-INF\persistence.xml
: - Create
.\src\main\webapp\WEB-INF\glassfish-resources.xml
: - Start webapp in embedded Glassfish server:
- Access REST endpoint to perform read/write operations:
- To stop server, send stop-domain command via web-request, after that press Ctrl+C in appropriate terminal window.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>jakartaee-hello-world</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>jakartaee-hello-world</name>
<description>
</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.report.sourceEncoding>UTF-8</project.report.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
<jakartaee-api.version>10.0.0</jakartaee-api.version>
<compiler-plugin.version>3.11.0</compiler-plugin.version>
<war-plugin.version>3.3.2</war-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>${jakartaee-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core -->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.2.6.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<build>
<!-- This bad boi becomes a parl of url and .war filename: -->
<finalName>myapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
package myapp.dao;
import java.util.List;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import myapp.model.Person;
@ApplicationScoped
public class PersonDao {
@PersistenceContext(unitName = "only-unit")
private EntityManager em;
@Transactional
public Person create(Person person) {
em.persist(person);
return person;
}
public List<Person> findAll() {
String queryString = "SELECT p FROM Person p";
var query = em.createQuery(queryString, Person.class);
var resultList = query.getResultList();
return resultList;
}
}
package myapp.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
package myapp.rest;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;
@ApplicationPath("/rest/*")
public class DemoApplication extends Application {
}
package myapp.rest;
import java.util.List;
import jakarta.inject.Inject;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import myapp.dao.PersonDao;
import myapp.model.Person;
@Path("person")
public class PersonResource {
@Inject
PersonDao personDao;
@GET
@Path("all")
@Produces({ MediaType.APPLICATION_JSON })
public List<Person> findAll() {
var list = personDao.findAll();
return list;
}
@POST
@Path("new")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes(MediaType.APPLICATION_JSON)
public Person create(Person person) {
person.setId(null);
System.out.println(person);
personDao.create(person);
return person;
}
}
<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="only-unit"
transaction-type="JTA" >
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:app/jdbc/embeddedDS</jta-data-source>
<properties>
<property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />
</properties>
</persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool
datasource-classname="org.apache.commons.dbcp2.BasicDataSource"
name="embeddedConnPool"
res-type="javax.sql.DataSource">
<property name="URL" value="jdbc:h2:mem:dataSource;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false" />
<property name="User" value="root" />
<property name="Password" value="qwerty" />
</jdbc-connection-pool>
<jdbc-resource jndi-name="java:app/jdbc/embeddedDS" pool-name="embeddedConnPool" enabled="true" />
</resources>
mvn clean package org.codehaus.cargo:cargo-maven3-plugin:run -Dcargo.maven.containerId=glassfish7x
curl.exe -X GET http://localhost:8080/myapp/rest/person/all/
curl.exe -X POST -H "Content-Type: application/json" -d '{"name":"Вася Петечкин"}' http://localhost:8080/myapp/rest/person/new
curl.exe -X GET http://localhost:4848/__asadmin/stop-domain -u admin:adminadmin