Browse Source

DATAJDBC-221 - Added AggregateReference for references across aggregates.

AggregateReferences can be used to reference other aggregates via their aggregate root without making them part of the referencing aggregate.
I.e. the referenced entities will not be included in SQL statements for the referencing aggregates, apart from their id.

Conversion between AggregateReferences and their ids and vice versa is done by the RelationalConverter.
pull/94/merge
Jens Schauder 8 years ago committed by Greg Turnquist
parent
commit
577d7643dd
No known key found for this signature in database
GPG Key ID: CB2FA4D512B5C413
  1. 11
      src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java
  2. 4
      src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java
  3. 63
      src/main/java/org/springframework/data/jdbc/core/mapping/AggregateReference.java
  4. 14
      src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java
  5. 30
      src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java
  6. 6
      src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java
  7. 11
      src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java
  8. 24
      src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java
  9. 121
      src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests.java
  10. 77
      src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterAggregateReferenceUnitTests.java
  11. 37
      src/test/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentPropertyUnitTests.java
  12. 1
      src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql

11
src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java

@ -285,13 +285,14 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy { @@ -285,13 +285,14 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
persistentEntity.doWithProperties((PropertyHandler<RelationalPersistentProperty>) property -> {
if (!property.isEntity()) {
if (property.isEntity()) {
return;
}
Object value = propertyAccessor.getProperty(property);
Object value = propertyAccessor.getProperty(property);
Object convertedValue = converter.writeValue(value, ClassTypeInformation.from(property.getColumnType()));
parameters.addValue(property.getColumnName(), convertedValue, JdbcUtil.sqlTypeFor(property.getColumnType()));
Object convertedValue = converter.writeValue(value, ClassTypeInformation.from(property.getColumnType()));
parameters.addValue(property.getColumnName(), convertedValue, JdbcUtil.sqlTypeFor(property.getColumnType()));
}
});
return parameters;

4
src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java

@ -99,7 +99,9 @@ public class EntityRowMapper<T> implements RowMapper<T> { @@ -99,7 +99,9 @@ public class EntityRowMapper<T> implements RowMapper<T> {
} else {
propertyAccessor.setProperty(property, readFrom(resultSet, property, ""));
final Object value = readFrom(resultSet, property, "");
propertyAccessor.setProperty(property, value);
}
}

63
src/main/java/org/springframework/data/jdbc/core/mapping/AggregateReference.java

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
/*
* Copyright 2018 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jdbc.core.mapping;
import lombok.RequiredArgsConstructor;
import org.springframework.lang.Nullable;
/**
* A reference to the aggregate root of a different aggregate.
*
* @param <T> the type of the referenced aggregate root.
* @param <ID> the type of the id of the referenced aggregate root.
*
* @author Jens Schauder
*
* @since 1.0
*/
public interface AggregateReference<T, ID> {
static <T, ID> AggregateReference<T, ID> to(ID id) {
return new IdOnlyAggregateReference<>(id);
}
/**
* @return the id of the referenced aggregate. May be {@code null}.
*/
@Nullable
ID getId();
/**
* An {@link AggregateReference} that only holds the id of the referenced aggregate root.
*
* Note that there is no check that a matching aggregate for this id actually exists.
*
* @param <T>
* @param <ID>
*/
@RequiredArgsConstructor
class IdOnlyAggregateReference<T, ID> implements AggregateReference<T, ID> {
private final ID id;
@Override
public ID getId() {
return id;
}
}
}

14
src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java

@ -27,6 +27,7 @@ import org.springframework.core.convert.support.DefaultConversionService; @@ -27,6 +27,7 @@ import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.convert.CustomConversions.StoreConversions;
import org.springframework.data.convert.EntityInstantiators;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
@ -49,6 +50,7 @@ import org.springframework.util.ClassUtils; @@ -49,6 +50,7 @@ import org.springframework.util.ClassUtils;
* Conversion is configurable by providing a customized {@link CustomConversions}.
*
* @author Mark Paluch
* @author Jens Schauder
* @see MappingContext
* @see SimpleTypeHolder
* @see CustomConversions
@ -157,6 +159,14 @@ public class BasicRelationalConverter implements RelationalConverter { @@ -157,6 +159,14 @@ public class BasicRelationalConverter implements RelationalConverter {
return conversionService.convert(value, type.getType());
}
if (AggregateReference.class.isAssignableFrom(type.getType())) {
TypeInformation<?> idType = type.getSuperTypeInformation(AggregateReference.class)
.getTypeArguments().get(1);
return AggregateReference.to(readValue(value, idType));
}
return getPotentiallyConvertedSimpleRead(value, type.getType());
}
@ -172,6 +182,10 @@ public class BasicRelationalConverter implements RelationalConverter { @@ -172,6 +182,10 @@ public class BasicRelationalConverter implements RelationalConverter {
return null;
}
if (AggregateReference.class.isAssignableFrom(value.getClass())) {
return writeValue (((AggregateReference) value).getId(), type);
}
Class<?> rawType = type.getType();
RelationalPersistentEntity<?> persistentEntity = context.getPersistentEntity(value.getClass());

30
src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java

@ -23,6 +23,8 @@ import java.util.Map; @@ -23,6 +23,8 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.jdbc.support.JdbcUtil;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
@ -96,6 +98,16 @@ class BasicRelationalPersistentProperty extends AnnotationBasedPersistentPropert @@ -96,6 +98,16 @@ class BasicRelationalPersistentProperty extends AnnotationBasedPersistentPropert
throw new UnsupportedOperationException();
}
@Override
public boolean isEntity() {
return super.isEntity() && !isReference();
}
@Override
public boolean isReference() {
return AggregateReference.class.isAssignableFrom(getRawType());
}
/*
* (non-Javadoc)
* @see org.springframework.data.jdbc.core.mapping.model.JdbcPersistentProperty#getColumnName()
@ -114,11 +126,20 @@ class BasicRelationalPersistentProperty extends AnnotationBasedPersistentPropert @@ -114,11 +126,20 @@ class BasicRelationalPersistentProperty extends AnnotationBasedPersistentPropert
@Override
public Class getColumnType() {
if (isReference()) {
return columnTypeForReference();
}
Class columnType = columnTypeIfEntity(getActualType());
return columnType == null ? columnTypeForNonEntity(getActualType()) : columnType;
}
@Override
public int getSqlType() {
return JdbcUtil.sqlTypeFor(getColumnType());
}
@Override
public RelationalPersistentEntity<?> getOwner() {
return (RelationalPersistentEntity<?>) super.getOwner();
@ -178,4 +199,13 @@ class BasicRelationalPersistentProperty extends AnnotationBasedPersistentPropert @@ -178,4 +199,13 @@ class BasicRelationalPersistentProperty extends AnnotationBasedPersistentPropert
.findFirst() //
.orElseGet(() -> ClassUtils.resolvePrimitiveIfNecessary(type));
}
private Class columnTypeForReference() {
Class<?> componentType = getTypeInformation().getRequiredComponentType().getType();
RelationalPersistentEntity<?> referencedEntity = context.getRequiredPersistentEntity(componentType);
return referencedEntity.getRequiredIdProperty().getColumnType();
}
}

6
src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java

@ -17,6 +17,7 @@ package org.springframework.data.relational.core.mapping; @@ -17,6 +17,7 @@ package org.springframework.data.relational.core.mapping;
import lombok.Getter;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
import org.springframework.data.mapping.context.AbstractMappingContext;
import org.springframework.data.mapping.context.MappingContext;
@ -78,4 +79,9 @@ public class RelationalMappingContext @@ -78,4 +79,9 @@ public class RelationalMappingContext
RelationalPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
return new BasicRelationalPersistentProperty(property, owner, simpleTypeHolder, this);
}
@Override
protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {
return super.shouldCreatePersistentEntityFor(type) && !AggregateReference.class.isAssignableFrom(type.getType());
}
}

11
src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java

@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
*/
package org.springframework.data.relational.core.mapping;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.lang.Nullable;
@ -26,6 +27,8 @@ import org.springframework.lang.Nullable; @@ -26,6 +27,8 @@ import org.springframework.lang.Nullable;
*/
public interface RelationalPersistentProperty extends PersistentProperty<RelationalPersistentProperty> {
boolean isReference();
/**
* Returns the name of the column backing this property.
*
@ -40,6 +43,14 @@ public interface RelationalPersistentProperty extends PersistentProperty<Relatio @@ -40,6 +43,14 @@ public interface RelationalPersistentProperty extends PersistentProperty<Relatio
*/
Class<?> getColumnType();
/**
* The SQL type constant used when using this property as a parameter for a SQL statement.
* @return Must not be {@code null}.
*
* @see java.sql.Types
*/
int getSqlType();
@Override
RelationalPersistentEntity<?> getOwner();

24
src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java

@ -25,6 +25,7 @@ import org.assertj.core.api.SoftAssertions; @@ -25,6 +25,7 @@ import org.assertj.core.api.SoftAssertions;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.jdbc.core.mapping.PersistentPropertyPathTestUtils;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.mapping.NamingStrategy;
@ -68,6 +69,7 @@ public class SqlGeneratorUnitTests { @@ -68,6 +69,7 @@ public class SqlGeneratorUnitTests {
.startsWith("SELECT") //
.contains("dummy_entity.x_id AS x_id,") //
.contains("dummy_entity.x_name AS x_name,") //
.contains("dummy_entity.x_other AS x_other,") //
.contains("ref.x_l1id AS ref_x_l1id") //
.contains("ref.x_content AS ref_x_content").contains(" FROM dummy_entity") //
// 1-N relationships do not get loaded via join
@ -139,9 +141,10 @@ public class SqlGeneratorUnitTests { @@ -139,9 +141,10 @@ public class SqlGeneratorUnitTests {
// this would get called when DummyEntity is the element type of a Set
String sql = sqlGenerator.getFindAllByProperty("back-ref", null, false);
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, "
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further "
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id "
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, " //
+ "dummy_entity.x_other AS x_other, " //
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further " //
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id " //
+ "WHERE back-ref = :back-ref");
}
@ -152,6 +155,7 @@ public class SqlGeneratorUnitTests { @@ -152,6 +155,7 @@ public class SqlGeneratorUnitTests {
String sql = sqlGenerator.getFindAllByProperty("back-ref", "key-column", false);
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, " //
+ "dummy_entity.x_other AS x_other, " //
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further, " //
+ "dummy_entity.key-column AS key-column " //
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id " //
@ -169,10 +173,11 @@ public class SqlGeneratorUnitTests { @@ -169,10 +173,11 @@ public class SqlGeneratorUnitTests {
// this would get called when DummyEntity is th element type of a Map
String sql = sqlGenerator.getFindAllByProperty("back-ref", "key-column", true);
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, "
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further, "
+ "dummy_entity.key-column AS key-column "
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id "
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, " //
+ "dummy_entity.x_other AS x_other, " //
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further, " //
+ "dummy_entity.key-column AS key-column " //
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id " //
+ "WHERE back-ref = :back-ref " + "ORDER BY key-column");
}
@ -222,6 +227,7 @@ public class SqlGeneratorUnitTests { @@ -222,6 +227,7 @@ public class SqlGeneratorUnitTests {
ReferencedEntity ref;
Set<Element> elements;
Map<Integer, Element> mappedElements;
AggregateReference<OtherAggregate, Long> other;
}
@SuppressWarnings("unused")
@ -250,7 +256,11 @@ public class SqlGeneratorUnitTests { @@ -250,7 +256,11 @@ public class SqlGeneratorUnitTests {
}
static class NoIdChild {
}
static class OtherAggregate {
@Id Long id;
String name;
}
private static class PrefixingNamingStrategy implements NamingStrategy {

121
src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests.java

@ -0,0 +1,121 @@ @@ -0,0 +1,121 @@
/*
* Copyright 2017-2018 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jdbc.repository;
import static org.assertj.core.api.Assertions.*;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.jdbc.testing.TestConfiguration;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.repository.CrudRepository;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;
import org.springframework.test.jdbc.JdbcTestUtils;
import org.springframework.transaction.annotation.Transactional;
/**
* Very simple use cases for creation and usage of JdbcRepositories.
*
* @author Jens Schauder
*/
@ContextConfiguration
@Transactional
public class JdbcRepositoryCrossAggregateHsqlIntegrationTests {
private static final long TWO_ID = 23L;
@Configuration
@Import(TestConfiguration.class)
@EnableJdbcRepositories(considerNestedRepositories = true)
static class Config {
@Autowired JdbcRepositoryFactory factory;
@Bean
Class<?> testClass() {
return JdbcRepositoryCrossAggregateHsqlIntegrationTests.class;
}
}
@ClassRule public static final SpringClassRule classRule = new SpringClassRule();
@Rule public SpringMethodRule methodRule = new SpringMethodRule();
@Autowired NamedParameterJdbcTemplate template;
@Autowired Ones ones;
@Autowired RelationalMappingContext context;
@SuppressWarnings("ConstantConditions")
@Test // DATAJDBC-221
public void savesAndRead() {
AggregateOne one = new AggregateOne();
one.name = "Aggregate - 1";
one.two = AggregateReference.to(TWO_ID);
one = ones.save(one);
AggregateOne reloaded = ones.findById(one.id).get();
assertThat(reloaded.two.getId()).isEqualTo(TWO_ID);
}
@Test // DATAJDBC-221
public void savesAndUpdate() {
AggregateOne one = new AggregateOne();
one.name = "Aggregate - 1";
one.two = AggregateReference.to(42L);
one = ones.save(one);
one.two = AggregateReference.to(TWO_ID);
ones.save(one);
assertThat( //
JdbcTestUtils.countRowsInTableWhere( //
(JdbcTemplate) template.getJdbcOperations(), //
"aggregate_one", //
"two = " + TWO_ID) //
).isEqualTo(1);
}
interface Ones extends CrudRepository<AggregateOne, Long> {}
static class AggregateOne {
@Id Long id;
String name;
AggregateReference<AggregateTwo, Long> two;
}
static class AggregateTwo {
@Id Long id;
String name;
}
}

77
src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterAggregateReferenceUnitTests.java

@ -0,0 +1,77 @@ @@ -0,0 +1,77 @@
/*
* Copyright 2018 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.relational.core.conversion;
import static org.assertj.core.api.Assertions.*;
import org.assertj.core.api.SoftAssertions;
import org.junit.Test;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.util.ClassTypeInformation;
/**
* Unit tests for the handling of {@link AggregateReference}s in the
* {@link org.springframework.data.relational.core.conversion.BasicRelationalConverter}.
*
* @author Jens Schauder
*/
public class BasicRelationalConverterAggregateReferenceUnitTests {
SoftAssertions softly = new SoftAssertions();
ConversionService conversionService = new DefaultConversionService();
RelationalMappingContext context = new RelationalMappingContext();
RelationalConverter converter = new BasicRelationalConverter(context);
RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(DummyEntity.class);
@Test // DATAJDBC-221
public void convertsToAggregateReference() {
final RelationalPersistentProperty property = entity.getRequiredPersistentProperty("reference");
Object readValue = converter.readValue(23, property.getTypeInformation());
assertThat(readValue).isInstanceOf(AggregateReference.class);
assertThat(((AggregateReference<DummyEntity, Long>) readValue).getId()).isEqualTo(23L);
}
@Test // DATAJDBC-221
public void convertsFromAggregateReference() {
final RelationalPersistentProperty property = entity.getRequiredPersistentProperty("reference");
AggregateReference<Object, Integer> reference = AggregateReference.to(23);
Object writeValue = converter.writeValue(reference, ClassTypeInformation.from(property.getColumnType()));
assertThat(writeValue).isEqualTo(23L);
}
private static class DummyEntity {
@Id
Long simple;
AggregateReference<DummyEntity, Long> reference;
}
}

37
src/test/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentPropertyUnitTests.java

@ -27,6 +27,8 @@ import java.util.UUID; @@ -27,6 +27,8 @@ import java.util.UUID;
import org.assertj.core.api.SoftAssertions;
import org.junit.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.mapping.PropertyHandler;
/**
@ -39,13 +41,14 @@ import org.springframework.data.mapping.PropertyHandler; @@ -39,13 +41,14 @@ import org.springframework.data.mapping.PropertyHandler;
public class BasicRelationalPersistentPropertyUnitTests {
RelationalMappingContext context = new RelationalMappingContext();
RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(DummyEntity.class);
@Test // DATAJDBC-104
public void enumGetsStoredAsString() {
RelationalPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class);
persistentEntity.doWithProperties((PropertyHandler<RelationalPersistentProperty>) p -> {
entity.doWithProperties((PropertyHandler<RelationalPersistentProperty>) p -> {
switch (p.getName()) {
case "someEnum":
assertThat(p.getColumnType()).isEqualTo(String.class);
@ -90,13 +93,26 @@ public class BasicRelationalPersistentPropertyUnitTests { @@ -90,13 +93,26 @@ public class BasicRelationalPersistentPropertyUnitTests {
public void detectsAnnotatedColumnAndKeyName() {
RelationalPersistentProperty listProperty = context //
.getRequiredPersistentEntity(DummyEntity.class) //
.getRequiredPersistentProperty("someList");
.getRequiredPersistentEntity(DummyEntity.class) //
.getRequiredPersistentProperty("someList");
assertThat(listProperty.getReverseColumnName()).isEqualTo("dummy_column_name");
assertThat(listProperty.getKeyColumn()).isEqualTo("dummy_key_column_name");
}
@Test // DATAJDBC-221
public void referencesAreNotEntitiesAndGetStoredAsTheirId() {
SoftAssertions softly = new SoftAssertions();
RelationalPersistentProperty reference = entity.getRequiredPersistentProperty("reference");
softly.assertThat(reference.isEntity()).isFalse();
softly.assertThat(reference.getColumnType()).isEqualTo(Long.class);
softly.assertAll();
}
private void checkTargetType(SoftAssertions softly, RelationalPersistentEntity<?> persistentEntity,
String propertyName, Class<?> expected) {
@ -106,11 +122,15 @@ public class BasicRelationalPersistentPropertyUnitTests { @@ -106,11 +122,15 @@ public class BasicRelationalPersistentPropertyUnitTests {
}
@Data
@SuppressWarnings("unused")
private static class DummyEntity {
@Id private final Long id;
private final SomeEnum someEnum;
private final LocalDateTime localDateTime;
private final ZonedDateTime zonedDateTime;
private final AggregateReference<DummyEntity, Long> reference;
private final List<String> listField;
private final UUID uuid;
@Column(value = "dummy_column_name", keyColumn = "dummy_key_column_name") private List<Integer> someList;
@ -122,9 +142,18 @@ public class BasicRelationalPersistentPropertyUnitTests { @@ -122,9 +142,18 @@ public class BasicRelationalPersistentPropertyUnitTests {
public LocalDateTime getLocalDateTime() {
return localDateTime;
}
public void setListSetter(Integer integer) {
}
public List<Date> getListGetter() {
return null;
}
}
@SuppressWarnings("unused")
private enum SomeEnum {
ALPHA;
ALPHA
}
}

1
src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql

@ -0,0 +1 @@ @@ -0,0 +1 @@
CREATE TABLE aggregate_one ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100), two INTEGER);
Loading…
Cancel
Save