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: