Move Sequence to RelationalPersistentProperty.

Sequence details are now maintained on the property level instead of using the entity level. This is a more accurate representation of the underlying model and that properties are annotated and not entities. It also allows future extension of expanding sequence support to general properties.

Extract delegate for sequence generation. Move types to org.springframework.data.jdbc.core.convert to resolve package cycles.

See #2003
Original pull request: #2005
This commit is contained in:
Mark Paluch
2025-04-09 10:30:32 +02:00
parent d0e43be314
commit eb25cc3ed4
16 changed files with 396 additions and 303 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2024-2025 the original author or authors.
* Copyright 2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jdbc.core.mapping;
package org.springframework.data.jdbc.core.convert;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
@@ -41,13 +41,13 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
/**
* Unit tests for {@link IdGeneratingBeforeSaveCallback}
* Unit tests for {@link IdGeneratingEntityCallback}
*
* @author Mikhail Polivakha
* @author Mark Paluch
*/
@MockitoSettings(strictness = Strictness.LENIENT)
class IdGeneratingBeforeSaveCallbackTest {
class IdGeneratingEntityCallbackTest {
@Mock NamedParameterJdbcOperations operations;
RelationalMappingContext relationalMappingContext;
@@ -64,7 +64,7 @@ class IdGeneratingBeforeSaveCallbackTest {
NamedParameterJdbcOperations operations = mock(NamedParameterJdbcOperations.class);
IdGeneratingBeforeSaveCallback subject = new IdGeneratingBeforeSaveCallback(relationalMappingContext,
IdGeneratingEntityCallback subject = new IdGeneratingEntityCallback(relationalMappingContext,
MySqlDialect.INSTANCE, operations);
EntityWithSequence processed = (EntityWithSequence) subject.onBeforeSave(new EntityWithSequence(),
@@ -76,7 +76,7 @@ class IdGeneratingBeforeSaveCallbackTest {
@Test // GH-1923
void entityIsNotMarkedWithTargetSequence() {
IdGeneratingBeforeSaveCallback subject = new IdGeneratingBeforeSaveCallback(relationalMappingContext,
IdGeneratingEntityCallback subject = new IdGeneratingEntityCallback(relationalMappingContext,
MySqlDialect.INSTANCE, operations);
NoSequenceEntity processed = (NoSequenceEntity) subject.onBeforeSave(new NoSequenceEntity(),
@@ -92,7 +92,7 @@ class IdGeneratingBeforeSaveCallbackTest {
when(operations.queryForObject(anyString(), any(SqlParameterSource.class), any(RowMapper.class)))
.thenReturn(generatedId);
IdGeneratingBeforeSaveCallback subject = new IdGeneratingBeforeSaveCallback(relationalMappingContext,
IdGeneratingEntityCallback subject = new IdGeneratingEntityCallback(relationalMappingContext,
PostgresDialect.INSTANCE, operations);
EntityWithSequence processed = (EntityWithSequence) subject.onBeforeSave(new EntityWithSequence(),
@@ -108,7 +108,7 @@ class IdGeneratingBeforeSaveCallbackTest {
when(operations.queryForObject(anyString(), any(SqlParameterSource.class), any(RowMapper.class)))
.thenReturn(generatedId);
IdGeneratingBeforeSaveCallback subject = new IdGeneratingBeforeSaveCallback(relationalMappingContext,
IdGeneratingEntityCallback subject = new IdGeneratingEntityCallback(relationalMappingContext,
PostgresDialect.INSTANCE, operations);
EntityWithIntSequence processed = (EntityWithIntSequence) subject.onBeforeSave(new EntityWithIntSequence(),
@@ -124,7 +124,7 @@ class IdGeneratingBeforeSaveCallbackTest {
when(operations.queryForObject(anyString(), any(SqlParameterSource.class), any(RowMapper.class)))
.thenReturn(generatedId);
IdGeneratingBeforeSaveCallback subject = new IdGeneratingBeforeSaveCallback(relationalMappingContext,
IdGeneratingEntityCallback subject = new IdGeneratingEntityCallback(relationalMappingContext,
PostgresDialect.INSTANCE, operations);
EntityWithUuidSequence processed = (EntityWithUuidSequence) subject.onBeforeSave(new EntityWithUuidSequence(),

View File

@@ -35,7 +35,7 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceCreator;
import org.springframework.data.annotation.Transient;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jdbc.core.mapping.IdGeneratingBeforeSaveCallback;
import org.springframework.data.jdbc.core.convert.IdGeneratingEntityCallback;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.support.SimpleJdbcRepository;
import org.springframework.data.jdbc.testing.IntegrationTest;
@@ -66,7 +66,7 @@ class JdbcRepositoryIdGenerationIntegrationTests {
@Autowired SimpleSeqRepository simpleSeqRepository;
@Autowired PersistableSeqRepository persistableSeqRepository;
@Autowired PrimitiveIdSeqRepository primitiveIdSeqRepository;
@Autowired IdGeneratingBeforeSaveCallback idGeneratingCallback;
@Autowired IdGeneratingEntityCallback idGeneratingCallback;
@Test // DATAJDBC-98
void idWithoutSetterGetsSet() {

View File

@@ -24,6 +24,7 @@ import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mockito.Mockito;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -37,7 +38,6 @@ import org.springframework.context.annotation.Profile;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.jdbc.core.convert.*;
import org.springframework.data.jdbc.core.dialect.JdbcDialect;
import org.springframework.data.jdbc.core.mapping.IdGeneratingBeforeSaveCallback;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
import org.springframework.data.jdbc.repository.config.DialectResolver;
@@ -45,7 +45,6 @@ import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.mapping.callback.EntityCallback;
import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.relational.RelationalManagedTypes;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.DefaultNamingStrategy;
import org.springframework.data.relational.core.mapping.NamingStrategy;
@@ -182,15 +181,15 @@ public class TestConfiguration {
}
/**
* Creates a {@link IdGeneratingBeforeSaveCallback} bean using the configured
* Creates a {@link IdGeneratingEntityCallback} bean using the configured
* {@link #jdbcDialect(NamedParameterJdbcOperations)}.
*
* @return must not be {@literal null}.
*/
@Bean
public IdGeneratingBeforeSaveCallback idGeneratingBeforeSaveCallback(JdbcMappingContext mappingContext,
public IdGeneratingEntityCallback idGeneratingBeforeSaveCallback(JdbcMappingContext mappingContext,
NamedParameterJdbcOperations operations, Dialect dialect) {
return Mockito.spy(new IdGeneratingBeforeSaveCallback(mappingContext, dialect, operations));
return Mockito.spy(new IdGeneratingEntityCallback(mappingContext, dialect, operations));
}
@Bean