Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
2a15259
Fix schema generator and query execution when entities have dynamic/c…
radovanradic Apr 28, 2025
602af16
fix(deps): update dependency io.micronaut:micronaut-core-bom to v4.8.…
renovate[bot] Apr 28, 2025
437c889
Fix for EmbeddedId regression in 4.0
radovanradic Apr 28, 2025
8f17328
Merge branch '4.12.x' into embeddedid-colname
radovanradic Apr 28, 2025
c688c3e
chore(deps): update softprops/action-gh-release action to v2.2.2 (#3404)
renovate[bot] Apr 28, 2025
46fc27f
fix(deps): update dependency org.springframework.boot:spring-boot-gra…
renovate[bot] Apr 29, 2025
2f35eac
fix(deps): update spring data (#3406)
renovate[bot] Apr 29, 2025
e647ccf
Don't use address prefix for embedded field
radovanradic Apr 29, 2025
a734546
Merge branch '4.12.x' into embeddedid-colname
radovanradic Apr 29, 2025
e1c9833
Add one more example for embedded and composite id
radovanradic Apr 29, 2025
64b1157
Disable gradle caching temporary
radovanradic Apr 29, 2025
70f769f
Revert gradle caching
radovanradic Apr 29, 2025
c3c5883
Add more tests for repo
radovanradic Apr 29, 2025
e9d666b
Remove trigger builds from workflow
radovanradic Apr 29, 2025
03cfb51
Fix issue with CursoredPageable and @EmbeddedId (#3411)
radovanradic Apr 30, 2025
4ad478c
Improve the Oracle client info feature. (#3405)
mikehearn Apr 30, 2025
70b14f5
fix(deps): update dependency io.micronaut:micronaut-core-bom to v4.8.…
renovate[bot] May 1, 2025
c5e4646
fix(deps): update dependency io.micronaut.coherence:micronaut-coheren…
renovate[bot] May 2, 2025
22695c2
[skip ci] Release v4.12.1
micronaut-build May 5, 2025
c771071
chore: Bump version to 4.12.2-SNAPSHOT
micronaut-build May 5, 2025
4886465
Merge branch '4.12.x' into embeddedid-colname
radovanradic May 5, 2025
4445e91
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Nov 5, 2025
8d8823a
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Nov 7, 2025
65e10b6
Fix tests
radovanradic Nov 7, 2025
f58c848
Revert formatting changes.
radovanradic Nov 7, 2025
70cc61f
Example for EmbeddedId naming strategy change
radovanradic Nov 9, 2025
55d5da7
Keep backward compatible EmbeddedId naming
radovanradic Nov 9, 2025
884b521
Add breaking changes documentation about composite id naming (@Embedd…
radovanradic Nov 9, 2025
c9ef288
Updated breaking changes documentation and tests.
radovanradic Nov 9, 2025
0d08c3a
Remove duplicated test example
radovanradic Nov 9, 2025
feabe3c
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Nov 10, 2025
a62cf87
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Nov 12, 2025
7ec83db
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Nov 28, 2025
a8137b0
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Dec 22, 2025
3883bed
Fix jakarta data test in data-processor
radovanradic Dec 22, 2025
db6cbba
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Dec 30, 2025
60c7ba3
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Jan 12, 2026
4301cc6
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Jan 16, 2026
71ac69c
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Jan 21, 2026
5553bb0
Merge remote-tracking branch 'origin/5.0.x' into embeddedid-colname
radovanradic Jan 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,13 @@ public class Restaurant {
private Address hqAddress;

public Restaurant(String name, Address address) {
this(name, address, null);
}

public Restaurant(String name, Address address, Address hqAddress) {
this.name = name;
this.address = address;
this.hqAddress = hqAddress;
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ class H2EmbeddedSpec extends Specification {
restaurant.address.street == 'Smith St.'
restaurant.address.zipCode == '1234'

when:"Find restaurant by street name"
restaurant = restaurantRepository.findByAddressStreet("Smith St.").orElse(null)
then:"Found restaurant"
restaurant
restaurant.name == "Joe's Cafe"

when:"Max by embedded property"
def maxStreet = restaurantRepository.getMaxAddressStreetByName("Fred's Cafe")
def minStreet = restaurantRepository.getMinAddressStreetByName("Fred's Cafe")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ class CountyPk {
@MappedEntity("comp_country")
class County {
@EmbeddedId
@MappedProperty("id")
CountyPk id
@MappedProperty
String countyName
Expand All @@ -620,6 +621,7 @@ class SettlementPk {
@MappedEntity("comp_settlement")
class Settlement {
@EmbeddedId
@MappedProperty("id")
SettlementPk id
@MappedProperty
String description
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class CustomEmbeddedNameMapping extends Specification implements H2TestPropertyP
def statements = encoder.buildCreateTableStatements(getRuntimePersistentEntity(MyBook))

then:
statements.join("\n") == 'CREATE TABLE "MyBook" ("id" VARCHAR(255) NOT NULL,"authorFirstName" VARCHAR(255) NOT NULL,"authorLastName" VARCHAR(255) NOT NULL,"authorDetailsIncludedNumberAge" INT NOT NULL, PRIMARY KEY("id"));'
statements.join("\n") == 'CREATE TABLE "MyBook" ("id" VARCHAR(255) NOT NULL,"firstName" VARCHAR(255) NOT NULL,"lastName" VARCHAR(255) NOT NULL,"numberAge" INT NOT NULL, PRIMARY KEY("id"));'
}

void "test build insert"() {
Expand All @@ -74,7 +74,7 @@ class CustomEmbeddedNameMapping extends Specification implements H2TestPropertyP
def res = builder.createCriteriaInsert(MyBook).build(new SqlQueryBuilder())

then:
res.query == 'INSERT INTO "MyBook" ("authorFirstName","authorLastName","authorDetailsIncludedNumberAge","id") VALUES (?,?,?,?)'
res.query == 'INSERT INTO "MyBook" ("firstName","lastName","numberAge","id") VALUES (?,?,?,?)'
}

void "test update"() {
Expand All @@ -89,7 +89,7 @@ class CustomEmbeddedNameMapping extends Specification implements H2TestPropertyP
def res = query.build(new SqlQueryBuilder())

then:
res.query == 'UPDATE "MyBook" SET "id"=?,"authorFirstName"=?,"authorLastName"=?,"authorDetailsIncludedNumberAge"=? WHERE ("id" = ?)'
res.query == 'UPDATE "MyBook" SET "id"=?,"firstName"=?,"lastName"=?,"numberAge"=? WHERE ("id" = ?)'
res.parameters == [
'1':'id',
'2':'author.firstName',
Expand All @@ -107,7 +107,7 @@ class CustomEmbeddedNameMapping extends Specification implements H2TestPropertyP
query.where(builder.equal(root.id(), builder.parameter(Object)))
def q = query.build(new SqlQueryBuilder())
then:
q.query == 'SELECT my_book_."id",my_book_."authorFirstName",my_book_."authorLastName",my_book_."authorDetailsIncludedNumberAge" FROM "MyBook" my_book_ WHERE (my_book_."id" = ?)'
q.query == 'SELECT my_book_."id",my_book_."firstName",my_book_."lastName",my_book_."numberAge" FROM "MyBook" my_book_ WHERE (my_book_."id" = ?)'
}

@Shared
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@

import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.tck.entities.Restaurant;
import io.micronaut.data.tck.repositories.RestaurantRepository;

import java.util.Optional;

@JdbcRepository(dialect = Dialect.H2)
public interface H2RestaurantRepository extends RestaurantRepository {

Optional<Restaurant> findByAddressStreet(String street);
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,13 @@ default String mappedName(List<Association> associations, PersistentProperty p
foreignAssociation = association;
}
final String originalAssocName = association.getName();
String assocName = association.getKind() == Relation.Kind.EMBEDDED ? association.getAnnotationMetadata().stringValue(MappedProperty.class).orElse(originalAssocName) : originalAssocName;
if (!sb.isEmpty()) {
sb.append(mappedAssociatedName(assocName));
} else {
sb.append(assocName);
String assocName = association.getKind() == Relation.Kind.EMBEDDED ? association.getAnnotationMetadata().stringValue(MappedProperty.class).orElse(StringUtils.EMPTY_STRING) : originalAssocName;
if (StringUtils.isNotEmpty(assocName)) {
if (!sb.isEmpty()) {
sb.append(mappedAssociatedName(assocName));
} else {
sb.append(assocName);
}
}
}
if (foreignAssociation != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,16 @@ class MongoEmbeddedSpec extends Specification implements MongoTestPropertyProvid

void "test save and retrieve entity with embedded"() {
when:"An entity is saved"
restaurantRepository.save(new Restaurant("Fred's Cafe", new Address("High St.", "7896")))
def restaurant = restaurantRepository.save(new Restaurant("Joe's Cafe", new Address("Smith St.", "1234")))
def firstRestaurant = restaurantRepository.save(new Restaurant("Fred's Cafe", new Address("High St.", "7896")))
def restaurant = restaurantRepository.save(new Restaurant("Joe's Cafe", new Address("Smith St.", "1234"), new Address("5th Boulevard", "1235")))

then:"The entity was saved"
restaurant
restaurant.id
restaurant.address.street == 'Smith St.'
restaurant.address.zipCode == '1234'
restaurant.hqAddress.street == '5th Boulevard'
restaurant.hqAddress.zipCode == '1235'

when:"The entity is retrieved"
restaurant = restaurantRepository.findById(restaurant.id).orElse(null)
Expand All @@ -53,7 +55,17 @@ class MongoEmbeddedSpec extends Specification implements MongoTestPropertyProvid
restaurant.id
restaurant.address.street == 'Smith St.'
restaurant.address.zipCode == '1234'
restaurant.hqAddress == null
restaurant.hqAddress.street == '5th Boulevard'
restaurant.hqAddress.zipCode == '1235'

when:"First restaurant is retrieved"
def loadedFirstRestaurant = restaurantRepository.findById(firstRestaurant.id).orElse(null)

then:"The embedded is populated correctly for first restaurant"
loadedFirstRestaurant.id == firstRestaurant.id
loadedFirstRestaurant.address.street == firstRestaurant.address.street
loadedFirstRestaurant.address.zipCode == firstRestaurant.address.zipCode
!loadedFirstRestaurant.hqAddress

when:"The object is updated with non-null value"
restaurant.hqAddress = new Address("John St.", "4567")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ interface MyRepository {
def encoded = criteriaQuery.build(encoder)

expect:
encoded.query.startsWith('SELECT restaurant_.`id`,restaurant_.`name`,restaurant_.`address_street`,restaurant_.`address_zip_code`,restaurant_.`hqaddress_street`,restaurant_.`hqaddress_zip_code` FROM')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think when there is

@Relation(Relation.Kind.EMBEDDED)
private final Address address;

or

@EmbeddedId
private PrimaryKey primaryKey;

then column should not be prefixed with address_ or primary_key_ and this was issue since while ago. This PR should fix it. Can cause some regression issue for existing apps, but the workaround would be adding @MappedProperty on embedded entity field.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct, and we can't cause regressions otherwise it has to go into next major version

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can postpone it for 5.0

encoded.query.startsWith('SELECT restaurant_.`id`,restaurant_.`name`,restaurant_.`street`,restaurant_.`zip_code`,restaurant_.`hqaddress_street`,restaurant_.`hqaddress_zip_code` FROM')
}

void "test h2 crud"() {
Expand Down Expand Up @@ -469,7 +469,7 @@ interface MyRepository {
def result = builder.createCriteriaInsert(Restaurant).build(new SqlQueryBuilder())

expect:
result.query == 'INSERT INTO "restaurant" ("name","address_street","address_zip_code","hqaddress_street","hqaddress_zip_code") VALUES (?,?,?,?,?)'
result.query == 'INSERT INTO "restaurant" ("name","street","zip_code","hqaddress_street","hqaddress_zip_code") VALUES (?,?,?,?,?)'
result.parameters.equals('1': 'name', '2':'address.street', '3':'address.zipCode', '4':'hqAddress.street', '5':'hqAddress.zipCode')
}

Expand All @@ -480,7 +480,7 @@ interface MyRepository {
def result = encoder.buildBatchCreateTableStatement(entity)

expect:
result == 'CREATE TABLE "restaurant" ("id" BIGINT PRIMARY KEY AUTO_INCREMENT,"name" VARCHAR(255) NOT NULL,"address_street" VARCHAR(255) NOT NULL,"address_zip_code" VARCHAR(255) NOT NULL,"hqaddress_street" VARCHAR(255),"hqaddress_zip_code" VARCHAR(255));'
result == 'CREATE TABLE "restaurant" ("id" BIGINT PRIMARY KEY AUTO_INCREMENT,"name" VARCHAR(255) NOT NULL,"street" VARCHAR(255) NOT NULL,"zip_code" VARCHAR(255) NOT NULL,"hqaddress_street" VARCHAR(255),"hqaddress_zip_code" VARCHAR(255));'
}

void "test encode insert statement - custom mapping strategy"() {
Expand Down Expand Up @@ -525,8 +525,8 @@ interface MyRepository {
]
query << [
'INSERT INTO "Shipment1" ("field","sp_country","sp_city") VALUES (?,?,?)',
'INSERT INTO "uuid_entity" ("name","child_id","xyz","embedded_child_embedded_child2_id","nullable_value","uuid") VALUES (?,?,?,?,?,?)',
'INSERT INTO "user_role_composite" ("id_user_id","id_role_id") VALUES (?,?)'
'INSERT INTO "uuid_entity" ("name","child_id","xyz","embedded_child2_id","nullable_value","uuid") VALUES (?,?,?,?,?,?)',
'INSERT INTO "user_role_composite" ("user_id","role_id") VALUES (?,?)'
]
}

Expand All @@ -547,8 +547,8 @@ interface MyRepository {
]
query << [
'CREATE TABLE "Shipment1" ("sp_country" VARCHAR(255) NOT NULL,"sp_city" VARCHAR(255) NOT NULL,"field" VARCHAR(255) NOT NULL, PRIMARY KEY("sp_country","sp_city"));',
'CREATE TABLE "uuid_entity" ("uuid" UUID,"name" VARCHAR(255) NOT NULL,"child_id" UUID,"xyz" UUID,"embedded_child_embedded_child2_id" UUID,"nullable_value" UUID, PRIMARY KEY("uuid"));',
'CREATE TABLE "user_role_composite" ("id_user_id" BIGINT NOT NULL,"id_role_id" BIGINT NOT NULL, PRIMARY KEY("id_user_id","id_role_id"));'
'CREATE TABLE "uuid_entity" ("uuid" UUID,"name" VARCHAR(255) NOT NULL,"child_id" UUID,"xyz" UUID,"embedded_child2_id" UUID,"nullable_value" UUID, PRIMARY KEY("uuid"));',
'CREATE TABLE "user_role_composite" ("user_id" BIGINT NOT NULL,"role_id" BIGINT NOT NULL, PRIMARY KEY("user_id","role_id"));'
]
}

Expand Down Expand Up @@ -621,7 +621,7 @@ interface MyRepository {
def q = query.where(builder.equal(root.id(), builder.parameter(Object))).build(encoder)

then:
q.query == 'SELECT project_."project_id_department_id",project_."project_id_project_id",LOWER(project_.name) AS name,project_.name AS db_name,UPPER(project_.org) AS org FROM "project" project_ WHERE (project_."project_id_department_id" = ? AND project_."project_id_project_id" = ?)'
q.query == 'SELECT project_."department_id",project_."project_id",LOWER(project_.name) AS name,project_.name AS db_name,UPPER(project_.org) AS org FROM "project" project_ WHERE (project_."department_id" = ? AND project_."project_id" = ?)'
q.parameters == [
'1': 'projectId.departmentId',
'2': 'projectId.projectId'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import io.micronaut.data.model.entities.Invoice
import io.micronaut.data.model.query.builder.sql.Dialect
import io.micronaut.data.model.query.builder.sql.SqlQueryBuilder
import io.micronaut.data.processor.entity.ActivityPeriodEntity
import io.micronaut.data.processor.entity.SomeEntity
import io.micronaut.data.processor.visitors.AbstractDataSpec
import io.micronaut.data.runtime.criteria.RuntimeCriteriaBuilder
import io.micronaut.data.tck.entities.Author
Expand Down Expand Up @@ -554,7 +555,7 @@ interface UserRoleRepository extends GenericRepository<UserRole, UserRoleId> {
def query = getQuery(method)

expect:
query == 'SELECT user_role_id_role_.`id`,user_role_id_role_.`name` FROM `user_role_composite` user_role_ INNER JOIN `role_composite` user_role_id_role_ ON user_role_.`id_role_id`=user_role_id_role_.`id` WHERE (user_role_.`id_user_id` = ?)'
query == 'SELECT user_role_id_role_.`id`,user_role_id_role_.`name` FROM `user_role_composite` user_role_ INNER JOIN `role_composite` user_role_id_role_ ON user_role_.`role_id`=user_role_id_role_.`id` WHERE (user_role_.`user_id` = ?)'
getParameterBindingIndexes(method) == ["0"] as String[]
getParameterBindingPaths(method) == ["id"] as String[]
getParameterPropertyPaths(method) == ["id.user.id"] as String[]
Expand Down Expand Up @@ -1003,10 +1004,10 @@ interface RestaurantRepository extends GenericRepository<Restaurant, Long> {
def findByAddressStreetQuery = getQuery(repository.getRequiredMethod("findByAddressStreet", String))
def getMaxAddressStreetByNameQuery = getQuery(repository.getRequiredMethod("getMaxAddressStreetByName", String))
expect:
findByNameQuery == 'SELECT restaurant_.`id`,restaurant_.`name`,restaurant_.`address_street`,restaurant_.`address_zip_code`,restaurant_.`hqaddress_street`,restaurant_.`hqaddress_zip_code` FROM `restaurant` restaurant_ WHERE (restaurant_.`name` = ?)'
saveQuery == 'INSERT INTO `restaurant` (`name`,`address_street`,`address_zip_code`,`hqaddress_street`,`hqaddress_zip_code`) VALUES (?,?,?,?,?)'
findByAddressStreetQuery == 'SELECT restaurant_.`id`,restaurant_.`name`,restaurant_.`address_street`,restaurant_.`address_zip_code`,restaurant_.`hqaddress_street`,restaurant_.`hqaddress_zip_code` FROM `restaurant` restaurant_ WHERE (restaurant_.`address_street` = ?)'
getMaxAddressStreetByNameQuery == 'SELECT MAX(restaurant_.`address_street`) FROM `restaurant` restaurant_ WHERE (restaurant_.`name` = ?)'
findByNameQuery == 'SELECT restaurant_.`id`,restaurant_.`name`,restaurant_.`street`,restaurant_.`zip_code`,restaurant_.`hqaddress_street`,restaurant_.`hqaddress_zip_code` FROM `restaurant` restaurant_ WHERE (restaurant_.`name` = ?)'
saveQuery == 'INSERT INTO `restaurant` (`name`,`street`,`zip_code`,`hqaddress_street`,`hqaddress_zip_code`) VALUES (?,?,?,?,?)'
findByAddressStreetQuery == 'SELECT restaurant_.`id`,restaurant_.`name`,restaurant_.`street`,restaurant_.`zip_code`,restaurant_.`hqaddress_street`,restaurant_.`hqaddress_zip_code` FROM `restaurant` restaurant_ WHERE (restaurant_.`street` = ?)'
getMaxAddressStreetByNameQuery == 'SELECT MAX(restaurant_.`street`) FROM `restaurant` restaurant_ WHERE (restaurant_.`name` = ?)'
}

void "test count query with joins"() {
Expand Down Expand Up @@ -1284,7 +1285,7 @@ interface UserRoleRepository extends GenericRepository<UserRole, UserRoleId> {
def countDistinctQuery = getQuery(repository.getRequiredMethod("countDistinct"))
expect:
countQuery == 'SELECT COUNT(*) FROM `user_role_composite` user_role_'
countDistinctQuery == 'SELECT COUNT(DISTINCT( CONCAT(user_role_.`id_user_id`,user_role_.`id_role_id`))) FROM `user_role_composite` user_role_'
countDistinctQuery == 'SELECT COUNT(DISTINCT( CONCAT(user_role_.`user_id`,user_role_.`role_id`))) FROM `user_role_composite` user_role_'
}

void "test many-to-one with properties starting with the same prefix"() {
Expand Down Expand Up @@ -1557,7 +1558,7 @@ interface UserRoleRepository extends GenericRepository<UserRole, UserRoleId> {

expect:
countQuery == 'SELECT COUNT(*) FROM `user_role_composite` user_role_'
countDistinctQuery == 'SELECT COUNT(DISTINCT( CONCAT(user_role_.`id_user_id`,user_role_.`id_role_id`))) FROM `user_role_composite` user_role_'
countDistinctQuery == 'SELECT COUNT(DISTINCT( CONCAT(user_role_.`user_id`,user_role_.`role_id`))) FROM `user_role_composite` user_role_'
}

void "test escape query"() {
Expand Down Expand Up @@ -1817,6 +1818,7 @@ class CountyPk {
@MappedEntity("comp_country")
class County {
@EmbeddedId
@MappedProperty(value = "id")
CountyPk id;
@MappedProperty
String countyName;
Expand All @@ -1841,6 +1843,7 @@ class SettlementPk {
@MappedEntity("comp_settlement")
class Settlement {
@EmbeddedId
@MappedProperty(value = "id")
SettlementPk id;
@MappedProperty
String description;
Expand Down Expand Up @@ -2412,7 +2415,7 @@ interface RestaurantRepository extends GenericRepository<Restaurant, Long> {

def method = repository.getRequiredMethod("find", String)
expect:
getQuery(method) == 'SELECT restaurant_.`id`,restaurant_.`name`,restaurant_.`address_street`,restaurant_.`address_zip_code`,restaurant_.`hqaddress_street`,restaurant_.`hqaddress_zip_code` FROM `restaurant` restaurant_ WHERE (restaurant_.`address_street` = ?)'
getQuery(method) == 'SELECT restaurant_.`id`,restaurant_.`name`,restaurant_.`street`,restaurant_.`zip_code`,restaurant_.`hqaddress_street`,restaurant_.`hqaddress_zip_code` FROM `restaurant` restaurant_ WHERE (restaurant_.`street` = ?)'
getParameterBindingIndexes(method) == ["0"] as String[]
getParameterBindingPaths(method) == [""] as String[]
getParameterPropertyPaths(method) == ["address.street"] as String[]
Expand Down Expand Up @@ -2469,4 +2472,33 @@ interface Repo extends GenericRepository<Book, Long> {
getOperationType(method) == DataMethod.OperationType.UPDATE
getRawQuery(method) == 'REPLACE INTO book (id, title, total_pages) VALUES (?, ?, ?)'
}

void "test EmbeddedId naming strategy"() {
given:
def repository = buildRepository('test.SomeEntityRepository', """
import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.repository.GenericRepository;
import io.micronaut.data.processor.entity.SomeEntity;
import jakarta.persistence.Embeddable;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import java.util.Optional;
@JdbcRepository(dialect = Dialect.H2)
interface SomeEntityRepository extends GenericRepository<SomeEntity, SomeEntity.PrimaryKey> {
Optional<SomeEntity> findById(SomeEntity.PrimaryKey id);
SomeEntity save(SomeEntity entity);
List<SomeEntity> findAll();
}
""")

def findByIdQuery = getQuery(repository.getRequiredMethod("findById", SomeEntity.PrimaryKey))
def saveQuery = getQuery(repository.getRequiredMethod("save", SomeEntity))
def findAllQuery = getQuery(repository.getRequiredMethod("findAll"))
expect:
findByIdQuery == 'SELECT some_entity_.`some_column`,some_entity_.`other_entity_id`,some_entity_.`col` FROM `some_table` some_entity_ WHERE (some_entity_.`some_column` = ? AND some_entity_.`other_entity_id` = ?)'
saveQuery == 'INSERT INTO `some_table` (`col`,`some_column`,`other_entity_id`) VALUES (?,?,?)'
findAllQuery == 'SELECT some_entity_.`some_column`,some_entity_.`other_entity_id`,some_entity_.`col` FROM `some_table` some_entity_'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class BuildTableSpec extends AbstractDataSpec {
sql.contains("\"hqaddress_street\" VARCHAR(255),")

and:"regular @Embedded does include NOT NULL declaration"
sql.contains("\"address_street\" VARCHAR(255) NOT NULL,")
sql.contains("\"street\" VARCHAR(255) NOT NULL,")
}

@Unroll
Expand Down
Loading
Loading