From cdb11ed44289e73866b58a3bf55ac6d242c8b775 Mon Sep 17 00:00:00 2001 From: radovanradic Date: Thu, 19 Sep 2024 18:51:39 +0200 Subject: [PATCH 1/2] Fix update by field when entity parameter is present --- .../criteria/UpdateCriteriaMethodMatch.java | 4 ++-- .../data/processor/sql/BuildUpdateSpec.groovy | 23 +++++++++++++++++++ .../tck/tests/AbstractRepositorySpec.groovy | 11 +++++++++ .../tck/repositories/PersonRepository.java | 2 ++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/data-processor/src/main/java/io/micronaut/data/processor/visitors/finders/criteria/UpdateCriteriaMethodMatch.java b/data-processor/src/main/java/io/micronaut/data/processor/visitors/finders/criteria/UpdateCriteriaMethodMatch.java index 6250abe381..c0e92576fb 100644 --- a/data-processor/src/main/java/io/micronaut/data/processor/visitors/finders/criteria/UpdateCriteriaMethodMatch.java +++ b/data-processor/src/main/java/io/micronaut/data/processor/visitors/finders/criteria/UpdateCriteriaMethodMatch.java @@ -170,12 +170,12 @@ protected Predicate interceptPredicate(MethodMatchContext matchContext, final SourcePersistentEntity rootEntity = (SourcePersistentEntity) root.getPersistentEntity(); Predicate predicate = null; if (entityParameter != null) { - if (rootEntity.getVersion() != null) { + if (rootEntity.getVersion() != null && existingPredicate == null) { predicate = cb.and( cb.equal(root.id(), cb.entityPropertyParameter(entityParameter, new PersistentPropertyPath(rootEntity.getIdentity()))), cb.equal(root.version(), cb.entityPropertyParameter(entityParameter, new PersistentPropertyPath(rootEntity.getVersion()))) ); - } else { + } else if (existingPredicate == null) { predicate = cb.equal(root.id(), cb.entityPropertyParameter(entityParameter, new PersistentPropertyPath(rootEntity.getIdentity()))); } } else { diff --git a/data-processor/src/test/groovy/io/micronaut/data/processor/sql/BuildUpdateSpec.groovy b/data-processor/src/test/groovy/io/micronaut/data/processor/sql/BuildUpdateSpec.groovy index 5c7585cfcf..95d0b62057 100644 --- a/data-processor/src/test/groovy/io/micronaut/data/processor/sql/BuildUpdateSpec.groovy +++ b/data-processor/src/test/groovy/io/micronaut/data/processor/sql/BuildUpdateSpec.groovy @@ -22,6 +22,7 @@ import io.micronaut.data.intercept.async.UpdateAsyncInterceptor import io.micronaut.data.intercept.reactive.UpdateReactiveInterceptor import io.micronaut.data.model.DataType import io.micronaut.data.processor.visitors.AbstractDataSpec +import io.micronaut.data.tck.entities.Person import spock.lang.PendingFeature import spock.lang.Unroll @@ -186,6 +187,28 @@ interface PersonRepository extends CrudRepository { } + void "test update by field with entity parameter"() { + given: + def repository = buildRepository('test.PersonRepository', """ +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.tck.entities.Person; + +@JdbcRepository(dialect = Dialect.MYSQL) +interface PersonRepository extends GenericRepository { + + void updateByName(String name, Person person); +} +""") + + def method = repository.findMethod("updateByName", String, Person).get() + def updateQuery = getQuery(method) + + expect: + updateQuery == 'UPDATE `person` SET `name`=?,`age`=?,`enabled`=?,`income`=? WHERE (`name` = ?)' + } + void "test AutoGenerated update method"() { given: def repository = buildRepository('test.StudentRepository', """ diff --git a/data-tck/src/main/groovy/io/micronaut/data/tck/tests/AbstractRepositorySpec.groovy b/data-tck/src/main/groovy/io/micronaut/data/tck/tests/AbstractRepositorySpec.groovy index cec02e195a..d86fe6b9c0 100644 --- a/data-tck/src/main/groovy/io/micronaut/data/tck/tests/AbstractRepositorySpec.groovy +++ b/data-tck/src/main/groovy/io/micronaut/data/tck/tests/AbstractRepositorySpec.groovy @@ -1007,6 +1007,17 @@ abstract class AbstractRepositorySpec extends Specification { then: personRepository.findByName("Jack") == null personRepository.findByName("Jeffrey").age == 30 + + when:"Update by using entity with null id" + def jeffrey = personRepository.findByName("Jeffrey") + def initialAge = jeffrey.age + jeffrey.id = null + jeffrey.age = 31 + personRepository.updateByName("Jeffrey", jeffrey) + def updatedJeffrey = personRepository.findByName("Jeffrey") + then:"Entity is updated" + initialAge == 30 + updatedJeffrey.age == 31 } void "test update by multiple fields"() { diff --git a/data-tck/src/main/java/io/micronaut/data/tck/repositories/PersonRepository.java b/data-tck/src/main/java/io/micronaut/data/tck/repositories/PersonRepository.java index 2f8cc23c3a..601b4fa8f0 100644 --- a/data-tck/src/main/java/io/micronaut/data/tck/repositories/PersonRepository.java +++ b/data-tck/src/main/java/io/micronaut/data/tck/repositories/PersonRepository.java @@ -81,6 +81,8 @@ public interface PersonRepository extends CrudRepository, Pageable long updateByName(String name, int age); + void updateByName(String name, Person person); + List list(Pageable pageable); int count(String name); From c01e0e114526fe80f373aeb14979919361baeb63 Mon Sep 17 00:00:00 2001 From: radovanradic Date: Thu, 19 Sep 2024 19:14:46 +0200 Subject: [PATCH 2/2] Use custom mssql docker images --- data-jdbc/src/test/resources/application.yml | 1 + data-r2dbc/src/test/resources/application.yaml | 1 + .../hibernate6/SqlServerHibernateTransactionSpec.groovy | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/data-jdbc/src/test/resources/application.yml b/data-jdbc/src/test/resources/application.yml index 5807b8f041..edca537035 100644 --- a/data-jdbc/src/test/resources/application.yml +++ b/data-jdbc/src/test/resources/application.yml @@ -3,6 +3,7 @@ test-resources: mssql: accept-license: true startup-timeout: 300s + image-name: mcr.microsoft.com/mssql/server:2022-latest mariadb: startup-timeout: 300s mysql: diff --git a/data-r2dbc/src/test/resources/application.yaml b/data-r2dbc/src/test/resources/application.yaml index d8aa464e64..838b600c7f 100644 --- a/data-r2dbc/src/test/resources/application.yaml +++ b/data-r2dbc/src/test/resources/application.yaml @@ -3,6 +3,7 @@ test-resources: mssql: accept-license: true startup-timeout: 300s + image-name: mcr.microsoft.com/mssql/server:2022-latest mariadb: startup-timeout: 300s mysql: diff --git a/data-tx-hibernate/src/test/groovy/io/micronaut/transaction/hibernate6/SqlServerHibernateTransactionSpec.groovy b/data-tx-hibernate/src/test/groovy/io/micronaut/transaction/hibernate6/SqlServerHibernateTransactionSpec.groovy index 8b1036f195..680fccdf72 100644 --- a/data-tx-hibernate/src/test/groovy/io/micronaut/transaction/hibernate6/SqlServerHibernateTransactionSpec.groovy +++ b/data-tx-hibernate/src/test/groovy/io/micronaut/transaction/hibernate6/SqlServerHibernateTransactionSpec.groovy @@ -17,7 +17,8 @@ class SqlServerHibernateTransactionSpec extends HibernateTransactionSpec impleme "datasources.default.name" : "mymssqldb", 'jpa.default.properties.hibernate.hbm2ddl.auto' : 'create-drop', 'jpa.default.properties.hibernate.dialect' : 'org.hibernate.dialect.SQLServerDialect', - 'test-resources.containers.mssql.accept-license' : 'true' + 'test-resources.containers.mssql.accept-license' : 'true', + 'test-resources.containers.mssql.image-name' : 'mcr.microsoft.com/mssql/server:2022-latest' ] }