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.261023 - next release (on main, not yet on Maven Central)​

The pet store was built with team rules on rc1 and the rule guide's examples were checked one by one; two places where what a rule wrote did not reach the running application are fixed. The runtime libraries gain a Spring Boot auto-configuration, so ports no longer need @EnableElastiCore. The 2.x generator and the jpa-springboot bundle produce the same output (only a return: decimal port, which did not compile, changes).

Team rules​

  • The v3 search endpoint validates its body (@Valid @RequestBody; v3, DDD, hexagonal, Kotlin): a constraint a rule puts on a search DTO (@Size(min = 2)) now answers 400 like create. Search DTOs generated today have no constraints, so nothing changes unless a rule, a hand edit or a sortableInterface/pageableInterface getter adds one. A controller you already edited stays as it is.
  • addMethod on a class without methods - an entity with fields only, an enum, an interface, a record - was dropped silently; it is now written before the closing brace. A file nothing is added to stays byte-identical.

Documentation​

  • Rule dev guide chapter 10, the rule API reference (@Rule, EntitySpec, SourceCode, addMethod, excludeMethod and its endpoint names, ModelCheck, ArtifactContributor, ...), now in the guide copied into every project, not only on this site. The rule API's javadoc no longer calls it a prototype.

Guide index​

  • blueprint/elasticore-guide-index.md - one line per guide section: <guide>:<first line>-<last line> <title> [terms], written from the copied guides, so a search for a term (@access) gives the range to read. A new file in blueprint/; the generated code does not change.

Ports without @EnableElastiCore​

  • Auto-configuration io.elasticore.springboot.autoconfigure.ElastiCoreAutoConfiguration in elasticore-springboot3 / -springboot4: it finds ports (@ExternalService, @DbmsService) in the @SpringBootApplication class's package and below and, only if there are any, registers them, DbTransactionGateway (one EntityManagerFactory or a @Primary one), ApplicationContextProvider and the banner. An application without ports gets nothing.
  • @EnableElastiCore still works, each piece registered once; beans you already have win. Off with elasticore.autoconfigure.enabled=false; elasticore.banner.enabled=false silences the banner.
  • Ports outside the application class's package (including scanBasePackages) are not found - use @AutoConfigurationPackage(basePackages = ...), @EnableElastiCore in that package, or a @Bean. With two or more EntityManagerFactory beans and none @Primary, mark one or declare a DbmsSqlExecutor. See Ports.
  • Ports that share a simple name are registered under their full class names, with a warning (they stopped the start before). Port proxies look up their beans in their own bean factory, which matters for tests with several contexts.

DBMS ports with one value​

  • A method returning one value (long, string, boolean, decimal) returns the first column, converted; a NULL value or no row gives null. Numbers failed with Failed to map tuple to DTO and a String came back empty.
  • return: decimal and List<decimal> generate java.math.BigDecimal (they generated decimal, which did not compile).
  • A single value parameter (long, string, a date, an enum) is bound to :name by its name (needs -parameters, set by Spring Boot's Gradle and Maven plugins); a single long was not bound. See DBMS ports.

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.