Skip to content

Commit c9815c0

Browse files
committedApr 25, 2025
Add support for composite ids.
Entities may be annotated with `@Id` and `@Embedded`, resulting in a composite id on the database side. The full embedded entity is considered the id, and therefore the check for determining if an aggregate is considered a new aggregate requiring an insert or an existing one, asking for an update is based on that entity, not its elements. Most use cases will require a custom `BeforeConvertCallback` to set the id for new aggregate. For an entity with `@Embedded` id, the back reference used in tables for referenced entities consists of multiple columns, each named by a concatenation of <table-name> + `_` + <column-name>. E.g. the back reference to a `Person` entity, with a composite id with the properties `firstName` and `lastName` will consist of the two columns `PERSON_FIRST_NAME` and `PERSON_LAST_NAME`. This holds for directly referenced entities as well as `List`, `Set` and `Map`. Closes #574 Original pull request #1957
1 parent 83650d9 commit c9815c0

File tree

42 files changed

+2393
-1033
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2393
-1033
lines changed
 

‎spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ public <T> Object insert(T instance, Class<T> domainType, Identifier identifier,
117117
public <T> Object[] insert(List<InsertSubject<T>> insertSubjects, Class<T> domainType, IdValueSource idValueSource) {
118118

119119
Assert.notEmpty(insertSubjects, "Batch insert must contain at least one InsertSubject");
120+
120121
SqlIdentifierParameterSource[] sqlParameterSources = insertSubjects.stream()
121122
.map(insertSubject -> sqlParametersFactory.forInsert( //
122123
insertSubject.getInstance(), //
@@ -167,7 +168,7 @@ public <S> boolean updateWithVersion(S instance, Class<S> domainType, Number pre
167168
public void delete(Object id, Class<?> domainType) {
168169

169170
String deleteByIdSql = sql(domainType).getDeleteById();
170-
SqlParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER);
171+
SqlParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType);
171172

172173
operations.update(deleteByIdSql, parameter);
173174
}
@@ -188,7 +189,7 @@ public <T> void deleteWithVersion(Object id, Class<T> domainType, Number previou
188189

189190
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(domainType);
190191

191-
SqlIdentifierParameterSource parameterSource = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER);
192+
SqlIdentifierParameterSource parameterSource = sqlParametersFactory.forQueryById(id, domainType);
192193
parameterSource.addValue(VERSION_SQL_PARAMETER, previousVersion);
193194
int affectedRows = operations.update(sql(domainType).getDeleteByIdAndVersion(), parameterSource);
194195

@@ -208,8 +209,7 @@ public void delete(Object rootId, PersistentPropertyPath<RelationalPersistentPro
208209

209210
String delete = sql(rootEntity.getType()).createDeleteByPath(propertyPath);
210211

211-
SqlIdentifierParameterSource parameters = sqlParametersFactory.forQueryById(rootId, rootEntity.getType(),
212-
ROOT_ID_PARAMETER);
212+
SqlIdentifierParameterSource parameters = sqlParametersFactory.forQueryById(rootId, rootEntity.getType());
213213
operations.update(delete, parameters);
214214
}
215215

@@ -243,7 +243,7 @@ public void deleteAll(PersistentPropertyPath<RelationalPersistentProperty> prope
243243
public <T> void acquireLockById(Object id, LockMode lockMode, Class<T> domainType) {
244244

245245
String acquireLockByIdSql = sql(domainType).getAcquireLockById(lockMode);
246-
SqlIdentifierParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER);
246+
SqlIdentifierParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType);
247247

248248
operations.query(acquireLockByIdSql, parameter, ResultSet::next);
249249
}
@@ -269,7 +269,7 @@ public long count(Class<?> domainType) {
269269
public <T> T findById(Object id, Class<T> domainType) {
270270

271271
String findOneSql = sql(domainType).getFindOne();
272-
SqlIdentifierParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER);
272+
SqlIdentifierParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType);
273273

274274
try {
275275
return operations.queryForObject(findOneSql, parameter, getEntityRowMapper(domainType));
@@ -355,7 +355,7 @@ public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
355355
public <T> boolean existsById(Object id, Class<T> domainType) {
356356

357357
String existsSql = sql(domainType).getExists();
358-
SqlParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER);
358+
SqlParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType);
359359

360360
Boolean result = operations.queryForObject(existsSql, parameter, Boolean.class);
361361
Assert.state(result != null, "The result of an exists query must not be null");

‎spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcBackReferencePropertyValueProvider.java

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.