Skip to main content

Basic Concepts

Understand ElastiCORE's core concepts and how they work to use the framework effectively.

ElastiCORE Architecture

Core Components

1. DSL (Domain Specific Language)

Define domain models using intuitive YAML-based syntax.

entity:
User:
meta: entity @expose(20) @audited
fields:
id: string(36)! @id @genid
username: string(50)! @search(like)
email: string(100)! @search(eq) @unique
isActive: boolean @default(true)

2. Annotation Processor

Detects the @EnableElastiCore annotation at compile time and initiates automatic code generation.

@EnableElastiCore  // This annotation starts the magic
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

3. Code Generation Engine

Analyzes blueprint definitions and auto-generates Java code following Spring Boot standard patterns.

Core Concepts

1. Blueprint

A systematic collection of YAML files that define the project's domain model.

src/main/resources/blueprint/
├── user/ # User domain
│ ├── env.yml # Environment config
│ ├── entity.yml # Entity definitions
│ └── dto.yml # DTO definitions
├── product/ # Product domain
│ ├── env.yml
│ └── model.yml
└── order/ # Order domain
└── models.yml

2. Domain

A logical unit that groups related entities and business logic.

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

namespace:
entity: com.example.user.entity
dto: com.example.user.dto
repository: com.example.user.repository
service: com.example.user.service
control: com.example.user.controller

3. Entity

Defines JPA entities that map to database tables.

entity:
User:
meta: entity @expose(20) @audited @table(app_users)
fields:
id: string(36)! @id @genid
username: string(50)! @search(like) @unique
email: string(100)! @search(eq) @unique
password: string(255)! @updatable(false)
profile: UserProfile @OneToOne @cascade(ALL)
roles: List<Role> @ManyToMany @cascade(PERSIST)
createdDate: datetime @jpa:org.springframework.data.annotation.CreatedDate
lastModifiedDate: datetime @jpa:org.springframework.data.annotation.LastModifiedDate

4. Search DTO

Automatically generated when using @expose or @searchable annotations — a dedicated DTO for dynamic search.

// Auto-generated SearchDTO:
public class UserSearchDTO implements PageableObject {
private String username; // @search(like) → partial match
private String email; // @search(eq) → exact match
private int pageNumber = 0; // pagination
private int pageSize = 20;
private String sortCode;
}

5. Entity Relationships

entity:
Post:
meta: entity @expose(10)
fields:
id: long @id @sequence
title: string(200)! @search(like)
content: text
author: User @ManyToOne @fetchjoin # Automatic N+1 resolution
comments: List<Comment> @OneToMany(mappedBy="post") @dtype(List<CommentDTO>)
tags: List<Tag> @ManyToMany @cascade(PERSIST)

Comment:
meta: entity @service(20) # Service only, no Controller
fields:
id: long @id @sequence
content: text!
post: Post @ManyToOne
author: User @ManyToOne @fetchjoin
createdDate: datetime @jpa:org.springframework.data.annotation.CreatedDate

Annotation System

Meta Annotations (Entity/DTO Level)

AnnotationDescriptionGenerated Code
@expose(n)REST API + search DTO auto-generationController + Service + SearchDTO
@service(n)Service only (no API)Service + SearchDTO only
@auditedJPA Envers audit tracking@Audited
@abstractAbstract entity (for inheritance)abstract class
@extend(Parent)Entity inheritanceextends ParentEntity
@table(name)Table name specification@Table(name = "custom_name")
@pageable(n)Default page sizePageable parameter added

Field Annotations

AnnotationDescriptionGenerated Code
@idPrimary key field@Id
@sequenceAuto-increment ID@GeneratedValue(IDENTITY)
@genidCustom ID generatorBased on env.yml settings
@search(type)Search conditionSearchDTO field generated
@default(value)Default valueDefault set in constructor
@uniqueUnique constraint@Column(unique = true)
@updatable(false)Immutable field@Column(updatable = false)
@fetchjoinJOIN FETCH optimizationAutomatic N+1 resolution

Search Annotations

entity:
Product:
meta: entity @expose(20)
fields:
name: string(100) @search(like) # Partial match (LIKE %name%)
sku: string(20) @search(eq) # Exact match (= sku)
price: bigdecimal(10,2) @search(between) # Range search (BETWEEN)
category: CategoryEnum @search(in) # Multi-select (IN)
rating: int @search(gte) # Greater than or equal (>=)
deletedDate: datetime @search(null) # IS NULL check

Code Generation Process

Generated File Structure

A single entity definition generates the complete Spring Boot stack:

// 1. JPA Entity
@Entity @Table(name = "users")
public class User { /* all JPA annotations and fields */ }

// 2. DTO
public class UserDTO { /* entity fields as DTO */ }

// 3. Search DTO (@expose only)
public class UserSearchDTO implements PageableObject { /* search fields */ }

// 4. Repository
@Repository
public interface UserRepository extends JpaRepository<User, String>,
JpaSpecificationExecutor<User> { }

// 5. Service
@Service @Transactional
public class UserService {
public Page<UserDTO> findBySearch(UserSearchDTO searchDTO, Pageable pageable);
public UserDTO create(UserDTO userDTO);
public UserDTO update(String id, UserDTO userDTO);
// ...
}

// 6. Controller (@expose only)
@RestController @RequestMapping("/api/users")
public class UserController { /* OpenAPI 3.0 documented REST API */ }

// 7. Test code (auto-generated)
@SpringBootTest
class UserServiceTest { /* JUnit 5 test cases */ }

Best Practices

1. Entity Design Pattern

entity:
# Base entity (all entities inherit from this)
BaseEntity:
meta: entity @abstract
fields:
createdDate: datetime @jpa:org.springframework.data.annotation.CreatedDate
createdBy: string(50) @jpa:org.springframework.data.annotation.CreatedBy
lastModifiedDate: datetime @jpa:org.springframework.data.annotation.LastModifiedDate
lastModifiedBy: string(50) @jpa:org.springframework.data.annotation.LastModifiedBy

# Auditable entity
AuditableEntity:
meta: entity @abstract @extend(BaseEntity) @audited
fields:
version: long @Version

# Concrete business entity
User:
meta: entity @expose(20) @extend(AuditableEntity)
fields:
id: string(36)! @id @genid
username: string(50)! @search(like) @unique
email: string(100)! @search(eq) @unique

2. Search Field Strategy

entity:
Product:
meta: entity @expose(20)
fields:
# Frequently searched fields
name: string(100)! @search(like)
sku: string(50)! @search(eq) @unique

# Filter fields
category: CategoryEnum @search(in)
isActive: boolean @search(eq) @default(true)

# Range search fields
price: bigdecimal(10,2) @search(between)
createdDate: datetime @search(between)

# Non-searchable fields (no @search)
description: text
internalNotes: text

FAQ

Q1: Can I modify the generated code directly?

A: Generated code will be overwritten on the next build. Use extension patterns instead:

@Service
@Primary
public class CustomUserService extends UserService {
@Override
public UserDTO create(UserDTO dto) {
validateUserCreation(dto);
return super.create(dto);
}
}

Q2: Where should I implement complex business logic?

A: Inherit from the generated Service or create a separate business service:

@Service
@Transactional
public class OrderBusinessService {
@Autowired private OrderService orderService; // Generated service
@Autowired private ProductService productService;

public OrderDTO processOrderWithDiscount(OrderCreateRequest request) {
validateProductStock(request.getItems());
BigDecimal discount = calculateDiscount(request);
return orderService.create(request.toOrderDTO());
}
}

Continue learning with more detailed guides: