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.
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)
| Annotation | Description | Generated Code |
|---|---|---|
@expose(n) | REST API + search DTO auto-generation | Controller + Service + SearchDTO |
@service(n) | Service only (no API) | Service + SearchDTO only |
@audited | JPA Envers audit tracking | @Audited |
@abstract | Abstract entity (for inheritance) | abstract class |
@extend(Parent) | Entity inheritance | extends ParentEntity |
@table(name) | Table name specification | @Table(name = "custom_name") |
@pageable(n) | Default page size | Pageable parameter added |
Field Annotations
| Annotation | Description | Generated Code |
|---|---|---|
@id | Primary key field | @Id |
@sequence | Auto-increment ID | @GeneratedValue(IDENTITY) |
@genid | Custom ID generator | Based on env.yml settings |
@search(type) | Search condition | SearchDTO field generated |
@default(value) | Default value | Default set in constructor |
@unique | Unique constraint | @Column(unique = true) |
@updatable(false) | Immutable field | @Column(updatable = false) |
@fetchjoin | JOIN FETCH optimization | Automatic 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:
- Entity Definition - Complete entity guide
- Annotations - All annotations reference
- Port Adapters - External system integration
- Examples - Real-world projects