Skip to content

Commit

Permalink
Potential option to support UPDATE RETURNING for JPA/Hibernate
Browse files Browse the repository at this point in the history
  • Loading branch information
radovanradic committed Oct 12, 2023
1 parent 6f6660b commit a76955f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,11 @@ public <R> List<R> execute(PreparedQuery<?, R> preparedQuery) {
}
return List.of((R) result);
} else {
throw new IllegalStateException("Not supported!");
if (preparedQuery.isNative()) {
Iterable<?> result = findAll(preparedQuery);
return (List<R>) result;
}
throw new IllegalStateException("Only native query supports update RETURNING operations.");
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.micronaut.data.hibernate

import io.micronaut.context.annotation.Property
import io.micronaut.data.hibernate.entities.UserWithWhere
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject

Expand All @@ -35,4 +36,21 @@ class HibernatePostgresQuerySpec extends AbstractHibernateQuerySpec {
animalRepository.add1(123) == 124
animalRepository.add1Alias(123) == 124
}

void "test updateReturning"() {
given:
def saved = new UserWithWhere(id: UUID.randomUUID(), email: "test@email.com", deleted: true)
userWithWhereRepository.save(saved)
when:"Update returning custom native query executed"
userWithWhereRepository.updateEmailById(saved.id, "test1@email.com")
def obj = userWithWhereRepository.updateReturningCustom("test2@email.com", false, saved.id)
then:"Object is returned"
noExceptionThrown()
obj
obj.email == "test2@email.com"
when:"Update email using native query and returning"
def updatedEmail = userWithWhereRepository.updateAndReturnEmail("test3@email.com", saved.id)
then:"Updated email value is returned"
updatedEmail == "test3@email.com"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.micronaut.data.hibernate;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.data.annotation.Query;
import io.micronaut.data.annotation.Repository;
import io.micronaut.data.hibernate.entities.UserWithWhere;
import io.micronaut.data.model.Sort;
Expand All @@ -13,4 +14,12 @@
public interface UserWithWhereRepository extends CrudRepository<UserWithWhere, UUID> {

List<UserWithWhere> findAllByIdInList(List<UUID> ids, @NonNull Sort sort);

@Query(value = "UPDATE users SET email = :email, deleted = :deleted WHERE id = :id RETURNING *", nativeQuery = true)
UserWithWhere updateReturningCustom(String email, boolean deleted, UUID id);

@Query(value = "UPDATE users SET email = :email WHERE id = :id RETURNING email", nativeQuery = true)
String updateAndReturnEmail(String email, UUID id);

void updateEmailById(UUID id, String email);
}
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,19 @@ class JpaQueryBuilderSpec extends Specification {
result.parameterTypes == ['name': DataType.STRING, 'id1': DataType.LONG, 'id2': DataType.LONG]
}

void "test update returning"() {
when:"Try build JPA query for UPDATE ... RETURNING"
QueryBuilder encoder = new JpaQueryBuilder()
def entity = getRuntimePersistentEntity(EntityWithIdClass)
def qm = QueryModel.from(entity)
qm.idEq(new QueryParameter("xyz"))
qm.projections().add(Projections.rootEntity())
encoder.buildUpdate(qm, ['name'])
then:"An exception will be thrown because it's not supported"
IllegalStateException ex = thrown()
ex.message == "Dialect: ANSI doesn't support UPDATE ... RETURNING clause"
}

@Shared
Map<Class, RuntimePersistentEntity> entities = [:]

Expand Down

0 comments on commit a76955f

Please sign in to comment.