Skip to main content
ElastiCORE 3.0 is a release candidate: 3.0.261022-rc1 on Maven Central. Projects on the 2.2 line: see the 2.2 documentation.
Version: 3.0

Release notes

The full history - every change with its reason, what was checked and the files involved - is elasticore-history.md (in Korean), in the repository and in every project's blueprint/ folder. Releases: GitHub releases · Maven Central.

Versions are {major}.{minor}.{YYMMDD}; a pre-release adds -alpha{n}, -beta{n} or -rc{n} and sorts before the release of the same line.

3.0.261022-rc1 - release candidate​

An agent was given the same requirement (a book, member and loan API) and later a pet store, built with ElastiCORE, and every place it wrote Java by hand was looked at. This release closes those gaps in the DSL. None of it changes the output of a project that does not use the new syntax, and the 2.x generator and the 2.x-compatible jpa-springboot bundle are unchanged (elcoreRulesCheck -Pstrict 150 MATCH / 0 DIFF / 2 ACCEPTED, elcoreTreeCheck 0 differ / 0 missing / 0 extra).

New in the DSL​

  • @readonly / @noinput are values the server sets - on the v3 bundles the mapper no longer writes them from a DTO to the entity, the DTO drops @NotNull/@NotBlank, and @Schema says READ_ONLY. Behaviour change: code that put such a value in a DTO and saved it must set it on the entity (beforeSave).
  • @search(isnull) - a <field>Empty: Boolean search property: true empty, false set (Java, Kotlin, TypeScript).
  • @pattern('regex', 'message') - a @Pattern that compiles, the message after the value like @min, the same check in the TypeScript client; a single \d is a DSL warning.
  • A required reference (post: Post!) requires the key field (postPostId) in save requests; the nested DTO is optional. Behaviour change for clients that sent only the nested object.
  • @signin on the entity line generates POST /signin, POST /signout, GET /me, me() and the TypeScript signIn/signOut/me() - only when only the member and the administrator may change the row, and with one @signin entity per application; the login column is made unique.
  • @default(now) documented with @readonly as the time a row is made; on timestamp it writes Instant.now(), and a timestamp's default no longer goes into the DTO.

Error answers​

  • A lifecycle step from the wrong state answers 409 (was 422); a key that names no row answers 404 (was a foreign-key 409), checked before saving (requireReferences; DDD and hexagonal bundles, references to another aggregate by id).
  • ConflictException and all hand-written refusals take a message code and are translated like generated ones: BadRequestException, NotFoundException, ConflictException, ForbiddenException, NotSignedInException, PortCallException.
  • PortCallException - a failed call of another system answers 502 (code: upstream).
  • RequestShapeErrors - what Spring MVC refuses before a controller (bad JSON, a wrong type, a missing parameter, 404, 405, 406, 415) answers problem+json with a code too.
  • The generated findById and delete answer a missing row with the same 404 body.
  • One language per answer: Accept-Language, else spring.web.locale, never the server machine's language; a translation in one domain is no longer hidden by another domain's English.

Generator and build​

  • @search(like) ignores case in v3 mode (hexagonal, DDD, -Pv3, Kotlin); @search(%_%) keeps it.
  • PUT /batch goes through update(dto) per row; @restExclude(update) takes batchUpdate with it and no longer breaks a hexagonal use case.
  • @minsize(1) also answers 400 for a missing list; an optional embedded value no longer makes its required fields NOT NULL columns; @updatable(false) on a reference keeps it; a @readonly owner keeps its owner.
  • A YAML file that does not parse (LOAD ERROR) stops elcore3; a DSL warning is printed once.
  • typescriptClient = true runs elcore3ts with the build; elcore3 warns about a client older than the model, and the client follows the server's mode.
  • Ossie: expressions as OSSIE_SQL_2026, subquery @formula as ANSI_SQL; count(Entity) counts the key column.
  • @EnableElastiCore scans its own class's package, so @SpringBootTest gets port beans; a @Primary wrapper of a port proxy works again; a 2.x application's component scan no longer picks up the error handler.
  • Fixes from three rounds of review: sign-in through @ref or a cascaded DTO cannot write another entity's login or password, inherited reference checks, value objects from other domains, @rollup discriminators as in 2.x.

3.0.261020-alpha2​

  • A Comment entity or enum in a domain no longer breaks compilation (@Comment written fully qualified where names clash).
  • The README's quick start in the real order of work, a build.gradle that works as copied, Spring Initializr and Spring Boot 3 notes; ReadmeQuickStartTest generates the README's quick start.
  • 3.0 is supported for three years from its first stable release, from release/3.0; Spring Boot 3 fixes are tested on 3.5.16.
  • CI also checks that the 2.x reference tree stays exactly as committed; the compatibility checks are described as they really compare.

3.0.261015-alpha1 - first public release​

  • The first release from the public repository: elasticore-base, elasticore-springboot3, elasticore-springboot4 and the Gradle plugin io.elasticore on Maven Central.
  • 2.x defects fixed where the output differs: @length(min=) with string(n), @formula (no column, not mapped from DTOs, = in expressions), both @ManyToOne relations to one target in search DTOs, @forceupdate mapping, values in generated service tests.
  • Domains and model files read in the same order on every operating system.
  • Security in the runtime: ignoreSSL on a multipart call no longer turns certificate checks off for the whole JVM; credentials masked in logs; IdUtils.newId uses SecureRandom.
  • The runtime POMs follow Spring Boot's dependency management instead of pinned old versions.

Upgrading from 2.2: change the version.