Skip to main content

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 @Audited annotation
  • 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 @Embeddable annotation
  • 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 indexes attribute 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, @size provide identical functionality

Compound Parameter Processing (Latest Enhancement):

  • JPA Column: Always uses the max value as the length attribute
  • Bean Validation: Both min and max are applied to the @Size annotation
  • 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 >= :price
    • lte: WHERE price <= :price
    • gt: WHERE price > :price
    • lt: 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 name
    • length: Column length
    • unique: Unique constraint
    • nullable: NULL allowance
  • Defaults:
    • name: Converts field name to snake_case (e.g., userName → user_name)
    • length: Length specified in field type or default value
    • unique: false
    • nullable: 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 @Pattern annotation
  • 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

@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

@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 @search annotations
  • Consider performance impact when using @cascade(ALL)
  • Adjust @expose page size for large collections
  • Consider memory usage when using values larger than the @pageable default (20)

9.3 Data Consistency

  • Use @relation(mappedBy) correctly when setting up bidirectional relationships
  • Leverage the combination of @updatable(false) and audit annotations
  • Ensure @Column parameter values match field type lengths

9.4 Using Defaults

  • @table annotation: Entity name → auto-converted to snake_case
  • @Column annotation: Field name → auto-converted to snake_case
  • @search annotation: Automatically selects optimal search conditions by field type

9.5 Security Considerations

  • Consider using @notaudited for sensitive fields
  • Set appropriate page size limits with @expose for API exposure
  • Be cautious of excessive pageSize settings when using @searchable