ElastiCORE Annotation Complete Guide
Overview
Complete reference for all annotations used in ElastiCORE DSL with detailed usage and examples.
1. Entity Meta Annotations
1.1 Basic Entity Declaration
meta: entity
- Description: Declares as a basic JPA entity
- Generated Code: Includes
@Entity,@Table
1.2 Abstract Entity
meta: entity @abstract
- Description: Abstract entity for inheritance only
- Generated Code: Generated as
abstract class - Usage: Defining common fields for BaseEntity, AuditEntity, etc.
1.3 Entity Inheritance
meta: entity @extend(ParentEntity)
- Description: Inherits from a parent entity
- Generated Code:
extends ParentEntity - Example:
entity:
AuditEntity:
meta: entity @abstract @extend(BaseEntity)
1.4 REST API Exposure
meta: entity @expose
meta: entity @expose(pageSize)
- Description: Exposes as REST API and auto-generates search DTOs
- Parameters:
pageSize- Default page size - Default: Automatically generates searchable fields (string: like, datetime: between)
- Generated Code: Generates Entity, DTO, Repository, Service, Controller, SearchDTO classes
- Example:
Article:
meta: entity @expose(50) # 50 items per page, SearchDTO generated
fields:
title: string(200)! # Automatically generates like search
1.5 Service Layer Only Exposure
meta: entity @service
meta: entity @service(pageSize)
- Description: Generates Service layer only without Controller, and auto-generates search DTOs
- Parameters:
pageSize- Default page size - Default: Automatically generates searchable fields (string: like, datetime: between)
- Generated Code: Generates Entity, DTO, Repository, Service, SearchDTO classes (excludes Controller)
- Usage: When used only in internal service logic without exposing as an external REST API
- Example:
InternalData:
meta: entity @service(30) # 30 items per page, no Controller generated
fields:
name: string(100)!
value: string(500)
1.6 Audit Target
meta: entity @audited
- Description: Data change history tracking via JPA Envers (dependency configuration required)
- Generated Code: Adds
@Auditedannotation - Usage: Managing change history for critical data
1.7 DTO Generation Marker
meta: entity @dto
- Description: Marks the entity as eligible for DTO generation
- Generated Code: Generates a separate DTO class
1.8 Pagination Support
meta: entity @pageable
meta: entity @pageable(50)
- Description: Enables pagination support
- Parameters:
pageSize- Items per page - Default:
20 - Generated Code: Generates methods that accept Pageable parameters
1.9 Embeddable Entity
meta: entity @embeddable
- Description: Declares as a JPA Embeddable entity
- Generated Code: Adds
@Embeddableannotation - Usage: Value objects such as addresses, coordinates
1.10 Table Name Specification
meta: entity @table(tableName)
meta: entity @tbl(tableName)
- Description: Explicitly specifies the database table name
- Parameters:
name- Table name - Default: Converts entity name to snake_case (e.g., UserInfo → user_info)
- Generated Code:
@Table(name = "tableName") - Example:
Address:
meta: entity @embeddable @table(customer_address)
# Default example (UserProfile → user_profile table)
UserProfile:
meta: entity
1.11 Index Definition
meta: entity @Index(name="idx_name", columnList="col1,col2")
meta: entity @Index(name="idx_name", columnList="col1,col2", unique=true)
meta: entity @idx(name="idx_name", columnList="col1,col2")
- Description: Defines a database index
- Parameters:
name: Index name (optional)columnList: Column list (required)unique: Unique constraint (optional)
- Default:
unique=false - Generated Code: Adds
indexesattribute within@Table - Example:
Message:
meta: entity @Index(name="idx_msg_create_date", columnList="create_date")
User:
meta: entity @Index(name="idx_user_email", columnList="email", unique=true)
2. Field Annotations
2.1 Primary Key Annotations
@id
fieldName: type @id
- Description: Designates as JPA primary key
- Generated Code:
@Id
@sequence
fieldName: long @id @sequence
- Description: Auto-increment sequence
- Generated Code:
@GeneratedValue(strategy = GenerationType.IDENTITY)
@genid
fieldName: string @id @genid
- Description: Uses a custom ID generator
- Generated Code: Refers to genid settings in env.yml
- Configuration:
annotations:
genid: "genid(io.elasticore.springboot3.util.IdUtils.newId)"
2.2 Data Constraint Annotations
@length(n) / @len(n) / @size(n) - String Length Limit and JPA Column Generation
- (Important) The type(length) syntax should be used as the primary approach. e.g., string(10)
# Simple length specification (existing approach)
fieldName: string(255)
fieldName: string @len(255)
fieldName: string @size(100)
# Compound length parameters (min/max simultaneous specification) - Latest feature
title: string @size(min=5, max=200) # Title (using alias)
Description: Sets the length limit for string fields and auto-generates JPA Column and Bean Validation
Parameter Format:
- Simple parameter:
@length(50)- Specifies maximum length only - Compound parameter:
@length(min=3, max=50)- Specifies both minimum and maximum length - Alias support:
@len,@sizeprovide identical functionality
Compound Parameter Processing (Latest Enhancement):
- JPA Column: Always uses the
maxvalue as thelengthattribute - Bean Validation: Both
minandmaxare applied to the@Sizeannotation - Alias handling: Works identically across all aliases:
length,len,size - Type recognition: Automatically distinguishes between Annotation.TYPE_KEY_VALUE and TYPE_SINGLE_VALUE
@default(value) - Field Default Value Setting with Smart Quoting
# Boolean and numeric defaults
fieldName: boolean @default(true)
salary: double @default(0)
point: int @default(100)
# String defaults - Smart quoting (latest enhancement)
status: string @default("ACTIVE") # Double quotes - kept as-is
category: string @default('GENERAL') # Single quotes - auto-converted to double quotes
archiveStatus: string @default(COMPLETED) # No quotes - auto-added
# Enumeration and special defaults
processType: ProcessType @default(ProcessType.HANG)
indicator: Indicator @default(Indicator.YES)
@updatable(false)
fieldName: datetime @updatable(false)
- Description: Non-updatable field
- Generated Code:
@Column(updatable = false)
@notnull
fieldName: string @notnull
- Description: NOT NULL constraint
- Generated Code:
@Column(nullable = false)
2.3 Search Annotations
@search(condition) / @searchable / @s / @srch / @filter
ElastiCORE supports various search conditions, automatically generating optimized queries and SearchDTO fields for each condition type.
1. LIKE Search (@search(like))
title: string @search(like)
productName: string @s(like)
- Usage: Partial string matching
- Generated Query:
WHERE LOWER(title) LIKE LOWER('%keyword%') - SearchDTO Field:
title: string(single input field)
2. Exact Match Search (@search(eq))
empNo: string @search(eq)
status: string @search(eq)
categoryId: long @search(eq)
- Usage: Exact value matching
- Generated Query:
WHERE empNo = :empNo
3. Range Search (@search(between))
createDate: datetime @search(between)
salary: double @search(between)
age: int @search(between)
- Usage: Range search for dates or numbers
- Generated Query:
WHERE createDate BETWEEN :createDateFrom AND :createDateTo - SearchDTO Fields:
createDateFrom: datetime(start value)createDateTo: datetime(end value)
4. IN Search (@search(in))
boardType: List<BoardType> @search(in)
categories: List<string> @search(in)
- Usage: Match any of multiple values
- Generated Query:
WHERE boardType IN (:boardTypeList)
5. Comparison Search (@search(gt), @search(lt), @search(gte), @search(lte))
price: double @search(gte) # Greater than or equal to
maxPrice: double @search(lte) # Less than or equal to
minAge: int @search(gt) # Greater than
score: double @search(lt) # Less than
- Usage: Numeric/date comparisons
- Generated Queries:
gte:WHERE price >= :pricelte:WHERE price <= :pricegt:WHERE price > :pricelt:WHERE price < :price
6. NULL Search (@search(null), @search(notnull))
description: string @search(null)
lastLogin: datetime @search(notnull)
- Usage: Check for NULL value existence
7. Alias Usage and Combinations
name: string @s(like) # Same as @search
status: string @srch(eq) # Same as @search
category: string @filter(in) # Same as @search
8. Default Behavior (Auto-selection)
title: string # Automatically applies @search(like)
createDate: datetime # Automatically applies @search(between)
status: StatusEnum # Automatically applies @search(eq)
tags: List<string> # Automatically applies @search(in)
9. Generated SearchDTO Example
# Source entity
entity:
Product:
meta: entity @expose(20)
fields:
productId: long @id @sequence
name: string(200)! @search(like)
price: double @search(between)
category: CategoryEnum @search(in)
createDate: datetime @search(between)
isActive: boolean @search(eq)
# Auto-generated SearchDTO
dto:
ProductSearchDTO:
fields:
name: string # Partial match search
priceFrom: double # Minimum price
priceTo: double # Maximum price
createDateFrom: datetime # Creation date start
createDateTo: datetime # Creation date end
category: List<CategoryEnum> # Category multi-select
isActive: boolean # Active status
pageNumber: int # Default: 0
pageSize: int # Default: 20
sortCode: string # Sort field
10. Search Condition Combination Examples
entity:
Order:
meta: entity @expose(30)
fields:
orderNo: string(20) @search(eq) # Exact order number search
customerName: string @search(like) # Partial customer name search
orderDate: datetime @search(between) # Order date range search
status: OrderStatus @search(in) # Multi-select status
amount: double @search(gte) # Minimum amount search
isPaid: boolean @search(eq) # Exact payment status search
2.4 Reference Annotations
@ref(fieldPath)
boardName: string @ref(board.name) # Simple reference
boardTypeName: string @ref(board.boardType.name) # Nested reference
- Description: References a field from another entity
- Usage: Retrieving field values from related entities in DTOs
@dtype(type)
articles: List<Article> @dtype(List<ArticleDTO>)
- Description: Specifies the type to use in DTO conversion
- Usage: Prevents circular references and ensures type safety
2.5 JPA Relationship Annotations
@OneToMany
articles: List<Article> @dtype(List<ArticleDTO>) @OneToMany(mappedBy="board")
- Generated Code:
@OneToMany(mappedBy = "board")
@ManyToOne
board: Board @ManyToOne
- Generated Code:
@ManyToOne
@ManyToMany
roles: List<Role> @ManyToMany
users: List<User> @ManyToMany(mappedBy="roles")
- Generated Code:
@ManyToMany
@OneToOne
profile: UserProfile @OneToOne
- Generated Code:
@OneToOne
@Embedded
address: Address @Embedded
coordinates: Location @Embedded
- Description: Embeds a JPA Embeddable object
- Generated Code:
@Embedded - Example:
User:
fields:
personalInfo: PersonalInfo @Embedded
homeAddress: Address @Embedded
workAddress: Address @Embedded
@cascade(type)
parameters: List<ParamInfo> @ManyToMany @cascade(ALL)
parts: List<CarPart> @cascade(PERSIST)
- Types: ALL, PERSIST, MERGE, REMOVE
- Generated Code:
cascade = CascadeType.ALL
@relation(mappedBy="fieldName")
address: Address @relation(mappedBy="market_post_id")
- Description: Designates the non-owning side in a bidirectional relationship
2.6 JPA Column Mapping
@Column / @col / @db
postNo: string(5) @Column(name="post_no", length=5)
carYear: Integer @Column(name="car_year")
username: string @col(unique=true)
email: string @db(name="email_addr", length=100)
- Parameters:
name: Column namelength: Column lengthunique: Unique constraintnullable: NULL allowance
- Defaults:
name: Converts field name to snake_case (e.g., userName → user_name)length: Length specified in field type or default valueunique:falsenullable:true
2.7 Field Validation Annotations
@pattern
email: string @pattern(regexp="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", message="Please enter a valid email address")
phoneNumber: string @pattern(regexp="^\\d{3}-\\d{4}-\\d{4}$", message="Phone number format must be 000-0000-0000")
- Description: Auto-generates Bean Validation
@Patternannotation - Parameters:
regexp: Regular expression pattern (required)message: Error message on validation failure (required)
- Framework compatibility: Automatically selects Jakarta/Javax package (based on j2ee setting in env.yml)
- Generated Java code:
@javax.validation.constraints.Pattern(
regexp="^[a-zA-Z0-9_]{3,50}$",
msg="Username must be 3-50 characters of letters, numbers, and underscores only"
)
private String username;
@min / @max - Numeric Range Validation and Bean Validation Generation
age: int @min(18) @max(65)
salary: double @min(0) @max(1000000)
price: double @min(0.01) @max(999999.99)
quantity: int @min(0) @max(999999)
Description: Restricts the value range of numeric type fields and auto-generates Bean Validation annotations
Parameters and Applicable Types:
- @min(value): Minimum allowed value (inclusive)
- @max(value): Maximum allowed value (inclusive)
- Applicable types:
int,long,double,float,BigDecimal,BigInteger
Auto-generated Code:
@Min(18)
@Max(65)
private Integer age;
@DecimalMin("0")
@DecimalMax("1000000")
private BigDecimal salary;
Distinction from @Size:
- @min/@max: Restricts the numeric value range (e.g., age 18–65)
- @minsize/@length: Restricts the size of strings or collections (e.g., string length 3–50 characters)
2.9 Custom Function Annotations
@function.get
fullName: string @function.get("getFullName")
displayName: string @function.get("generateDisplayName")
- Description: Specifies a custom Getter method for the field
@function.set
password: string @function.set("setEncryptedPassword")
email: string @function.set("setNormalizedEmail")
- Description: Specifies a custom Setter method for the field
2.10 Spring Data JPA Audit Annotations
@jpa:CreatedDate
createDate: datetime @jpa:org.springframework.data.annotation.CreatedDate
- Generated Code:
@CreatedDate
@jpa:CreatedBy
createdBy: string(20) @jpa:org.springframework.data.annotation.CreatedBy
- Generated Code:
@CreatedBy
@jpa:LastModifiedDate
lastModifiedDate: datetime @jpa:org.springframework.data.annotation.LastModifiedDate
- Generated Code:
@LastModifiedDate
@jpa:LastModifiedBy
lastModifiedBy: string(20) @jpa:org.springframework.data.annotation.LastModifiedBy
- Generated Code:
@LastModifiedBy
2.11 Audit Exclusion
@notaudited
temporaryData: string @notaudited
- Generated Code:
@NotAudited
2.12 Environment Configuration Reference
@env:annotationName
coordinates: int[] @env:integerarray
tags: string[] @env:stringarray
userId: string @env:genid
- Description: References annotation settings from env.yml
- Usage: Reusable custom annotations
3. DTO Annotations
3.1 Template-based DTO
dto:
ArticleDTO:
meta: dto @template(Article)
fields:
createDate: -- # Exclude field
- @template(EntityName): Specifies the base entity, or copies field information from another referenced template definition.
- --: Excludes a specific field inherited from the template
3.2 Search DTO
dto:
ArticleSearchDTO:
meta: dto @searchable(entity=Article, pageSize=50)
# or
meta: dto @searchable(entity=Article, pageSize=50, pageable=true)
- @searchable: Generates a search-only DTO
- Parameters:
entity: Target entity name (required)pageSize: Page size (default:100)pageable: Enable pagination (default:true)
- Generated Fields:
pageNumber: Page number (default: 0)pageSize: Page size (configured value)sortCode: Sort field name
3.3 Multiple Template Inheritance
dto:
CarProfileInfoDTO:
meta: dto @template(CarProfileDTO,CarInfoDTO)
- Description: Combines multiple DTOs to create a new DTO
3.4 JSON-related Annotations
@json / @jsonproperty
userName: string @json("user_name")
fullName: string @jsonproperty("full_name")
createDate: datetime @json("created_at")
- Description: Specifies the property name used for JSON serialization/deserialization
- Generated Code:
@JsonProperty("property_name")
@jsonSerialize
amount: BigDecimal @jsonSerialize(using=com.example.MoneySerializer)
- Description: Specifies a custom JSON serializer class
- Generated Code:
@JsonSerialize(using = CustomSerializer.class)
@jsoninclude / @includejson
optionalField: string @jsoninclude
description: string @includejson
- Description: Sets conditions for JSON serialization inclusion
3.5 Search-related Annotations
@searchBypass
dto:
UserDTO:
fields:
internalId: string @searchBypass
tempData: string @searchBypass
- Description: Excludes the field from search conditions when generating the search DTO
4. Enumeration Annotations
4.1 Basic Enumeration
enumeration:
BoardType:
meta: enum @db(code) @json(code)
- @db(fieldName): Database storage field
- @json(fieldName): JSON serialization field
4.2 Field Constraints
enumeration:
BoardType:
fields:
code: string(2) # Maximum length limit
5. Port Annotations
5.1 Database Port
port:
BoardService:
meta: dbms @datasource("main")
- dbms: Direct database integration
- @datasource(name): Specifies the datasource
5.2 HTTP Port
port:
ExternalApiPort:
meta: http @url("https://api.example.com")
- http: HTTP API integration
- @url(baseUrl): Specifies the base URL
5.3 Authentication Configuration
port:
SecureApiPort:
meta: http @url("https://api.example.com") @auth(API-KEY-123)
- @auth(credentials): Authentication credentials
5.4 HTTP Method Annotations
methods:
getUserInfo:
meta: method @get("/users/{userId}")
createUser:
meta: method @post("/users")
updateUser:
meta: method @put("/users/{userId}")
deleteUser:
meta: method @delete("/users/{userId}")
- Supported methods:
@get,@post,@put,@delete,@patch
5.5 HTTP Endpoint
methods:
complexMethod:
meta: method @HttpEndpoint(url="/api/complex", method="POST")
params:
body: RequestData @body
- @HttpEndpoint: Detailed HTTP configuration
- @body: Request body parameter
6. Protocol Buffer Annotations
6.1 gRPC Service
service:
UserService:
meta: proto @server @client
- proto: Protocol Buffer based
- @server: Generates gRPC server code
- @client: Generates gRPC client code
7. Composite Annotation Examples
7.1 Complete Entity Definition - Latest Feature Examples
entity:
User:
meta: entity @expose(20) @audited @Index(name="idx_user_email", columnList="email")
fields:
userId: long @id @sequence
username: string(50) @search(like) @default("new_user") @pattern(regexp="^[a-zA-Z0-9_]{3,50}$", message="Username must be 3-50 characters of letters, numbers, and underscores only")
email: string(150) @search(eq) @Column(unique=true) @pattern(regexp="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", message="Please enter a valid email address")
password: string(255) @minsize(8) @function.set("setEncryptedPassword") @default('temporary123')
displayName: string(100) @function.get("generateDisplayName")
firstName: string(50) @default('FirstName')
lastName: string(50) @default(LastName)
status: UserStatus @default(UserStatus.ACTIVE)
isActive: boolean @default(true)
isEmailVerified: boolean @default(false)
roles: List<Role> @dtype(List<RoleDTO>) @ManyToMany @cascade(ALL)
personalInfo: PersonalInfo @Embedded
createdDate: datetime @updatable(false) @jpa:org.springframework.data.annotation.CreatedDate @default(now())
lastModifiedDate: datetime @jpa:org.springframework.data.annotation.LastModifiedDate
lastLoginDate: datetime @search(between)
registrationIp: string(4%) @default("127.0.0.1")
profile: UserProfile @OneToOne @cascade(ALL)
7.2 Audit-based Entity - Latest Feature Examples
entity:
AuditableEntity:
meta: entity @abstract @audited
fields:
createdDate: datetime @updatable(false) @jpa:org.springframework.data.annotation.CreatedDate
createdBy: string(20) @updatable(false) @jpa:org.springframework.data.annotation.CreatedBy
lastModifiedDate: datetime @jpa:org.springframework.data.annotation.LastModifiedDate
lastModifiedBy: string(20) @jpa:org.springframework.data.annotation.LastModifiedBy
version: long @Column(name="version_no") @Version
7.3 Composite Search DTO - Advanced Search Feature Examples
dto:
UserSearchDTO:
meta: dto @searchable(entity=User, pageSize=25, pageable=true)
fields:
creditScore: int @search(between) @min(300) @max(850)
statusList: List<UserStatus> @search(in)
roles: List<Role> @search(in)
isActive: boolean @search(eq)
isEmailVerified: boolean @search(eq)
createdDate: datetime @search(between)
7.4 JSON and DTO Comprehensive Example
dto:
UserResponseDTO:
meta: dto @template(User)
fields:
userId: long @searchBypass
userName: string(50) @json("user_name")
emailAddress: string(150) @jsonproperty("email")
displayName: string @function.get("generateDisplayName") @default("User")
firstName: string @json("first_name") @default('FirstName')
fullName: string @json("full_name") @default(FullName)
8. Parameter Processing Patterns
8.1 Dot Notation
ElastiCORE uses dot notation for annotation parameter access:
meta: dto @searchable(entity=User, pageSize=50, pageable=true)
# Internal processing:
# searchable.entity → "User"
# searchable.pageSize → "50"
# searchable.pageable → "true"
8.2 Default Value Processing Logic
// Code example: @pageable annotation processing
String pageSizeVal = metaInfo.getMetaAnnotationValue("pageable");
if(pageSizeVal == null)
pageSizeVal = "20"; // Apply default value
8.3 Parameter Validation
- Numeric parameters use default values on parse failure
- Missing required parameters cause compilation errors
- Type mismatches fall back to default values
9. Notes and Best Practices
9.1 Annotation Order
- Meta annotations come first, followed by field-specific annotations
- Group related annotations together
9.2 Performance Considerations
- Set appropriate indexes when using
@searchannotations - Consider performance impact when using
@cascade(ALL) - Adjust
@exposepage size for large collections - Consider memory usage when using values larger than the
@pageabledefault (20)
9.3 Data Consistency
- Use
@relation(mappedBy)correctly when setting up bidirectional relationships - Leverage the combination of
@updatable(false)and audit annotations - Ensure
@Columnparameter values match field type lengths
9.4 Using Defaults
@tableannotation: Entity name → auto-converted to snake_case@Columnannotation: Field name → auto-converted to snake_case@searchannotation: Automatically selects optimal search conditions by field type
9.5 Security Considerations
- Consider using
@notauditedfor sensitive fields - Set appropriate page size limits with
@exposefor API exposure - Be cautious of excessive pageSize settings when using
@searchable