> ## Content Index
> Fetch the complete content index at: https://www.ggorantala.dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# Spring Boot Hello World Tutorial with Lombok and H2 Database – Quick Start for Beginners
- URL: https://www.ggorantala.dev/spring-boot-hello-world-tutorial-with-lombok-and-h2-database/
- Published: 2025-05-08T00:45:34.000Z
- Updated: 2025-05-08T01:33:33.000Z
- Description: Learn how to create a Hello World Spring Boot application using Lombok for cleaner code and the H2 in-memory database for rapid development. This step-by-step guide includes annotations, project setup, REST API, H2 console access, and more to kickstart your Spring Boot journey.
- Author: Gopi Gorantala
- Tags: Spring Boot Tutorials, Spring, spring-boot, spring boot microservices, Java

Below is a deep-dive into each of the four Java classes in your “Hello World” Spring Boot project, with an eye toward SOLID design, layering, and best practices.

## 🔧 pom.xml - Maven dependencies

```xml
<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>dev.ggorantala</groupId>
  <artifactId>hello-lombok-h2</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.4</version>
    <relativePath/> 
  </parent>

  <properties>
    <java.version>17</java.version>
  </properties>

  <dependencies>
    <!-- Web starter for REST endpoints -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- JPA + Hibernate -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- In-memory H2 database -->
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      <scope>runtime</scope>
    </dependency>

    <!-- Lombok for getters/setters/etc. -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.28</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <!-- Enables annotation-processing for Lombok -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <annotationProcessorPaths>
            <path>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
              <version>1.18.28</version>
            </path>
          </annotationProcessorPaths>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
```

## 📁 Project Structure

```
hello-world/
├── src/main/java/com/example/helloworld/
│   ├── HelloWorldApplication.java
│   ├── controller/HelloController.java
│   ├── model/User.java
│   ├── repository/UserRepository.java
│   └── data/DataLoader.java
└── src/main/resources/
    └── application.properties

```

## 🏁 Main Class

```java
package dev.ggorantala.hellolombokh2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloLombokH2Application {
    public static void main(String[] args) {
        SpringApplication.run(HelloLombokH2Application.class, args);
    }
}

```

**Entry point** of the application (the “composition root”). Lives in the **bootstrap** layer: it brings together all other beans and starts the Spring context.

**Key Annotations**

1. `@SpringBootApplication` \= `@Configuration` \+ `@EnableAutoConfiguration` \+ `@ComponentScan`.
  1. `**@Configuration**`: lets you declare extra `@Bean` definitions if needed.
  2. **`@EnableAutoConfiguration`**: tells Spring Boot to configure your app based on classpath dependencies (e.g., JPA, Web, H2).
  3. `**@ComponentScan**`: scans your package (and subpackages) for Spring stereotypes (`@Service`, `@Repository`, `@Controller`, etc.).

**SOLID & Patterns**

- **Single Responsibility**: only boots and wires up the context.
- **Open/Closed**: adding new beans (services, controllers) doesn’t require modifying this class.
- **Dependency Injection**: empowers the rest of your code to rely on abstractions rather than manually instantiating objects.

## 🌐 Simple REST Controller

```java
package dev.ggorantala.hellolombokh2.controller;

import dev.ggorantala.hellolombokh2.model.Greeting;
import dev.ggorantala.hellolombokh2.repository.GreetingRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private final GreetingRepository repo;

    @Autowired
    public GreetingController(GreetingRepository repo) {
        this.repo = repo;
    }

    @GetMapping("/hello")
    public String hello() {
        // save a new Greeting to H2 and return its message
        Greeting g = repo.save(new Greeting(null, "Hello, World!"));
        return g.getMessage();
    }
}

```

**Web / API layer**: handles HTTP requests and returns responses.

**Key Annotations**

1. `@RestController`: shorthand for `@Controller` \+ `@ResponseBody`—methods return data directly in the HTTP body (no view resolution).
2. `@GetMapping("/hello")`: maps GET requests for `/hello` to this method.
3. `@Autowired` on the constructor:
  1. **Constructor injection** is preferred (over field/setter) for immutability and easier testing.

**Method Logic**

1. Creates and saves a new `Greeting` entity with the text “Hello, World!”.
2. Returns the persisted `message` (so you see the exact string).

**SOLID & Patterns**

- **Single Responsibility**: only handles HTTP mapping and delegates persistence.
- **Open/Closed**: to add more endpoints, create new methods—no need to touch existing mappings.
- **Dependency Inversion**: depends on the `GreetingRepository` interface.
- **Stateless** controller: no mutable fields beyond the injected repository, making it thread-safe.

## 🧍‍♂️Entity Class with Lombok

```java
package dev.ggorantala.hellolombokh2.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;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Greeting {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String message;
}

```

**Domain model** / **JPA entity** in the **persistence** layer. Maps to a table (by default named `greeting`) in H2.

**Key Annotations**

1. `@Entity`: marks this class as a managed JPA entity.
2. `@Id` \+ `@GeneratedValue`: designates `id` as the primary key with auto-generated values.
3. **Lombok**
  1. `@Data`: generates getters/setters, `equals()`, `hashCode()`, and a nice `toString()`.
  2. `@NoArgsConstructor` / `@AllArgsConstructor`: boilerplate constructors for JPA and convenience.

**SOLID & Patterns**

- **Single Responsibility**: encapsulates only the persistence fields and behavior of a “Greeting.”
- **Encapsulation**: fields are private, access via methods generated by Lombok.
- No business logic here—kept lean to respect the **Layered Architecture** (separate domain/persistence from service/controller).

## 🗃️ Repository Interface

```java
package dev.ggorantala.hellolombokh2.repository;

import dev.ggorantala.hellolombokh2.model.Greeting;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface GreetingRepository extends JpaRepository<Greeting, Long> { }

```

**Data access** abstraction in the **repository** layer. Hides JPA/Hibernate boilerplate behind well-known CRUD methods.

**Key Annotations & Interfaces**

1. `@Repository`:
  1. Marks it as a Spring bean for component scanning.
  2. Translates JPA exceptions into Spring’s `DataAccessException` hierarchy.
2. Extends `JpaRepository<Greeting, Long>`: provides
  1. CRUD methods (`save()`, `findAll()`, `findById()`, `delete()`, etc.).
  2. Pagination and sorting out of the box.

**SOLID & Patterns**

- Implements the **Repository Pattern**, keeping data operations isolated from business logic.
- **Dependency Inversion**: higher layers (services/controllers) depend on this abstraction, not on concrete JPA code.

## Annotation & Configuration Breakdown

| Annotation / Property        | What it does                                                                          |
| ---------------------------- | ------------------------------------------------------------------------------------- |
| @SpringBootApplication       | Combines @Configuration, @EnableAutoConfiguration, and @ComponentScan. Boots the app. |
| @Entity                      | Marks a class as a JPA entity to be persisted in the database.                        |
| @Id                          | Designates the primary-key field of the entity.                                       |
| @GeneratedValue              | Configures automatic key generation strategy for the entity.                          |
| @Data (Lombok)               | Generates getters/setters, toString(), equals() & hashCode().                         |
| @NoArgsConstructor (Lombok)  | Generates a no-argument constructor.                                                  |
| @AllArgsConstructor (Lombok) | Generates a constructor with 1 parameter per field.                                   |
| @Repository                  | Indicates a Spring Data repository; exception translation, etc.                       |
| @RestController              | Combines @Controller \+ @ResponseBody. Defines a REST endpoint.                       |
| @GetMapping("/hello")        | Maps HTTP GET /hello to this method.                                                  |
| @Autowired                   | Injects the GreetingRepository bean into the controller.                              |

## ⚙️ application.properties

```properties
# H2 in-memory datasource
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

# Show SQL in console (optional)
spring.jpa.show-sql=true

# Enable H2 console
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

```

## 🔗 H2 Console

- **URL:** <http://localhost:8080/h2-console>
- **JDBC URL:** `jdbc:h2:mem:testdb`
- **User:** `sa`
- **Password:** *(leave blank)*

Once you start the app and navigate to that URL, you can inspect the `GREETING` table and any data you’ve persisted.

### How They Fit Together

1. **Startup**: Spring Boot scans your package, finds `@SpringBootApplication`, brings up the context, and auto-configures H2, JPA, Web, and Lombok.
2. **Request**: A GET to `http://localhost:8080/hello` hits `GreetingController.hello()`.
3. **Persistence**: The controller uses `GreetingRepository` to save a new `Greeting` to H2.
4. **Response**: Controller returns the persisted message back to the client.
5. **Inspect DB**: You can browse the `GREETING` table via the H2 console at `/h2-console`.

Each class plays its own role, keeps responsibilities narrow, and relies on Spring’s inversion-of-control to wire everything neatly—demonstrating strong adherence to SOLID and common design patterns.