Skip to main content

Create Your First Project

In this tutorial, you'll build a complete user management system with ElastiCORE in just 5 minutes.

What You'll Get

By the end of this tutorial, you'll have:

  • A User entity with full CRUD API
  • REST API with search by name and email
  • Automatic pagination and sorting support
  • H2 database with web console access

Prerequisites

  • Java 17+ installed
  • IntelliJ IDEA or VS Code (annotation processing support required)
  • ElastiCORE project template ready

Step-by-Step Guide

Step 1: Create the Base Project Structure

Add ElastiCORE dependencies to your Spring Boot project (via Spring Initializr or existing project).

build.gradle
dependencies {
// ElastiCORE core dependencies
implementation 'io.elasticore:elasticore-base:1.8.250924-SNAPSHOT'
implementation 'io.elasticore.springboot3:elasticore-springboot3:1.8.250924-SNAPSHOT'

// Spring Boot base stack
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'

// H2 database (for development)
runtimeOnly 'com.h2database:h2'

// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}

// ElastiCORE code generation task
tasks.register('elcore', JavaExec) {
classpath = sourceSets.main.runtimeClasspath
mainClass = 'io.elasticore.base.extract.ModelExtractor'
args "$projectDir/src/main/java"
}

Step 2: Configure the Main Application Class

Application.java
package com.example.myproject;

import io.elasticore.springboot3.EnableElastiCore;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableElastiCore // Activates ElastiCORE
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

Step 3: Create the Environment Configuration

src/main/resources/blueprint/env.yml
elasticore:
enable: true
config:
domainName: user
framework: springboot
mode: jpa
j2ee: jakarta

# Auto-generate test code
testCode:
enabled: true
framework: junit5
mockFramework: mockito

namespace:
entity: com.example.myproject.domain.entity
dto: com.example.myproject.domain.dto
repository: com.example.myproject.domain.repository
service: com.example.myproject.domain.service
control: com.example.myproject.web.controller

Step 4: Define the Domain Model

src/main/resources/blueprint/models.yml
entity:
User:
meta: entity @expose(20) @audited
fields:
id: string(36)! @id @genid
username: string(50)! @search(like) @unique
email: string(100)! @search(eq) @unique
fullName: string(100) @search(like)
isActive: boolean @default(true) @search(eq)
createdDate: datetime @jpa:org.springframework.data.annotation.CreatedDate
lastModifiedDate: datetime @jpa:org.springframework.data.annotation.LastModifiedDate

UserProfile:
meta: entity @service(10) # Service only, no Controller
fields:
id: string(36)! @id @genid
user: User @OneToOne @cascade(ALL) @fetchjoin
bio: text @search(like)
avatarUrl: string(500)
website: string(300)
location: string(100) @search(like)
createdDate: datetime @jpa:org.springframework.data.annotation.CreatedDate

Step 5: Configure Spring Boot

application.yml
spring:
datasource:
url: jdbc:h2:mem:devdb;DB_CLOSE_DELAY=-1
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
h2:
console:
enabled: true
path: /h2-console

logging:
level:
io.elasticore: DEBUG
org.springframework.web: INFO

Step 6: Generate Code and Build

# 1. Generate ElastiCORE code
./gradlew elcore

# 2. Compile the project
./gradlew compileJava

# 3. Run the application
./gradlew bootRun

On successful execution, you'll see output like:

ElastiCORE Code Generation completed:
- Generated 2 entities: User, UserProfile
- Generated 4 DTOs: UserDTO, UserSearchDTO, UserProfileDTO, UserProfileSearchDTO
- Generated 2 repositories with Specification support
- Generated 2 services with CRUD operations
- Generated 1 controller with REST API
- Generated 6 test classes

Started Application in 2.847 seconds

Auto-Generated Code Structure

ElastiCORE generates a complete Spring Boot stack:

src/main/java/com/example/myproject/
├── domain/
│ ├── entity/
│ │ ├── User.java # JPA entity (fully annotated)
│ │ └── UserProfile.java # 1:1 relationship entity
│ ├── dto/
│ │ ├── UserDTO.java # Data transfer object
│ │ ├── UserSearchDTO.java # Dynamic search DTO
│ │ ├── UserProfileDTO.java
│ │ └── UserProfileSearchDTO.java
│ ├── repository/
│ │ ├── UserRepository.java # JpaRepository + JpaSpecificationExecutor
│ │ └── UserProfileRepository.java
│ └── service/
│ ├── UserService.java # Complete CRUD + search logic
│ └── UserProfileService.java
└── web/
└── controller/
└── UserController.java # OpenAPI-documented REST API

Testing the API

1. Access Swagger UI

Open http://localhost:8080/swagger-ui.html in your browser to view the auto-generated API documentation.

2. Auto-Generated REST API Endpoints

User Management API:
GET /api/users # List users (paginated)
GET /api/users/{id} # Get specific user
POST /api/users # Create new user
PUT /api/users/{id} # Update user
DELETE /api/users/{id} # Delete user
GET /api/users/search # Dynamic search API

UserProfile Management API:
- Service layer only (no REST API)
- Use UserProfileService via dependency injection

3. Create a User

curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{
"username": "johndoe",
"email": "john.doe@example.com",
"fullName": "John Doe",
"isActive": true
}'

The auto-generated search API is very powerful:

# Partial username search (LIKE)
curl "http://localhost:8080/api/users/search?username=john"

# Exact email search (EQUALS)
curl "http://localhost:8080/api/users/search?email=john.doe@example.com"

# Active users only
curl "http://localhost:8080/api/users/search?isActive=true"

# Combined search conditions
curl "http://localhost:8080/api/users/search?username=john&isActive=true"

# Pagination and sorting
curl "http://localhost:8080/api/users/search?username=john&pageNumber=0&pageSize=10&sortCode=createdDate,desc"

5. H2 Database Console

  1. Go to http://localhost:8080/h2-console
  2. Connection details:
    • JDBC URL: jdbc:h2:mem:devdb
    • Username: sa
    • Password: (blank)

Customization & Extension

1. Adding Custom Business Logic

Extend the generated service to add your own logic:

CustomUserService.java
@Service
@Primary // Use this class instead of the default UserService
public class CustomUserService extends UserService {

@Autowired
private UserProfileService userProfileService;

public UserDTO createUserWithProfile(UserDTO userDTO, UserProfileDTO profileDTO) {
UserDTO createdUser = super.create(userDTO);
profileDTO.setUserId(createdUser.getId());
userProfileService.create(profileDTO);
return createdUser;
}
}

2. Extending Search Conditions

Modify the model and regenerate to add more search conditions:

models.yml - adding search conditions
entity:
User:
fields:
createdDate: datetime @jpa:org.springframework.data.annotation.CreatedDate @search(between)
# Date range search auto-generated: createdDateFrom, createdDateTo

Next Steps

You've successfully completed your first project! Continue learning:

Troubleshooting

1. Code Generation Not Running

# Solution:
# 1. Verify @EnableElastiCore annotation is on the main class
# 2. Check blueprint directory path
# 3. Run: ./gradlew clean elcore

2. Compilation Errors

# Error: cannot find symbol: class UserService
# Solution: Generate code first, then compile
./gradlew elcore
./gradlew compileJava

3. 404 Error on API Calls

# Cause: Controller not generated
# Solution: Verify @expose annotation
entity:
User:
meta: entity @expose(20) # This annotation is required for Controller generation

Development Tips
  1. Incremental development: Start with a small model and gradually expand
  2. Code review: Read the generated code to learn ElastiCORE patterns
  3. Test first: Run the auto-generated test code first
  4. Documentation: Use Swagger UI for automatic API documentation