Skip to main content

Other Features

Save Command Result

The result returned by a save command is an object, e.g. SimpleSaveResult<E>/KSimpleSaveResult<E> for the save method that saves a single object.

The result supports the following behaviors:

  • originalEntity property: Returns the original parameter passed to the save method by the developer.

  • modifiedEntity property: A data structure identical in shape to originalEntity, with the differences:

    • If originalEntity contains some objects without id properties that rely on id generation strategies (e.g. auto increment, sequence, UUID, snowflake id etc.), the corresponding objects in modifiedEntity will necessarily have the id property set to the value automatically assigned by the database/application.

    • If some objects belong to entity types with optimistic locking fields, the version properties of the corresponding objects in modifiedEntity will have the latest version number after modification.

    info

    modifiedEntity is discussed many times in previous docs, so is not elaborated here.

  • totalAffectedRowCount property: The execution of a save command may modify multiple tables in the database. This property summarizes the total number of affected rows across all modified tables.

  • getAffectedRowCountMap property: A map of affected tables and their affected row counts.

  • getAffectedRowCount method, taking a parameter to get the affected row count of the specified table. Accepts two kinds of parameters:

    • Entity type: Gets affected row count of the table corresponding to this entity type.

    • Association property based on join table: Gets affected row count of the join table corresponding to this association property.

Let's look at some examples of the totalAffectedRowCount property and getAffectedRowCount method:

SimpleSaveResult<Book> result = sqlClient.update(
Objects.createBook(draft -> {
draft.setId(3L);
draft.setPrice(new BigDecimal("59.9"));
draft.addIntoAuthors(author -> author.setId(1L));
draft.addIntoAuthors(author -> author.setId(3L));
draft.addIntoAuthors(author -> {
author.setId(1000L); // does not exist, created automatically
author.setFirstName("Svetlana");
author.setLastName("Isakova");
author.setGender(Gender.FEMALE);
});
})
);
System.out.println(
"Total affected row count: " +
result.getTotalAffectedRowCount()
);
System.out.println(
"Affected row count for entity table BOOK: " +
result.getAffectedRowCount(Book.class)
);
System.out.println(
"Affected row count for entity table AUTHOR: " +
result.getAffectedRowCount(Author.class)
);
System.out.println(
"Affected row count for join table BOOK_AUTHOR_MAPPING: " +
result.getAffectedRowCount(BookProps.AUTHORS)
);
tip

The code getAffectedRowCount(BookProps.AUTHORS) is equivalent to getAffectedRowCount(AuthorProps.BOOKS)

The printed result is:

Total affected row count: 5
Affected row count for entity table BOOK: 1
Affected row count for entity table AUTHOR: 1
Affected row count for join table BOOK_AUTHOR_MAPPING: 3

The explanation is:

  • The affected row count for table BOOK is 1:

    The price of the aggregate root object Book(id=3L) is modified.

  • The affected row count for table AUTHOR is 1:

    The associated object Author(id=1000L) does not exist and is created automatically.

  • The affected row count for table BOOK_AUTHOR_MAPPING is 3:

    • Dissociation between Book(id=3L) and Author(id=2L) (For dissociation operations on join tables, this is deleting the association).

    • New association between Book(id=3L) and Author(id=3L).

    • New association between Book(id=3L) and Author(id=1000L).