Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class BasicRelationalPersistentProperty extends AnnotationBasedPersistent
private final @Nullable ValueExpression collectionKeyColumnNameExpression;
private final boolean isEmbedded;
private final String embeddedPrefix;
private final String embeddedSuffix;

private final NamingStrategy namingStrategy;
private boolean forceQuote = true;
Expand Down Expand Up @@ -89,6 +90,9 @@ public BasicRelationalPersistentProperty(Property property, PersistentEntity<?,
this.embeddedPrefix = Optional.ofNullable(findAnnotation(Embedded.class)) //
.map(Embedded::prefix) //
.orElse("");
this.embeddedSuffix = Optional.ofNullable(findAnnotation(Embedded.class)) //
.map(Embedded::suffix) //
.orElse("");

Lazy<Optional<SqlIdentifier>> collectionIdColumnName = null;
Lazy<SqlIdentifier> collectionKeyColumnName = Lazy
Expand Down Expand Up @@ -269,6 +273,11 @@ public String getEmbeddedPrefix() {
return isEmbedded() ? embeddedPrefix : "";
}

@Override
public String getEmbeddedSuffix() {
return isEmbedded() ? embeddedSuffix : "";
}

@Override
public boolean shouldCreateEmptyEmbedded() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
*/
String prefix() default "";

/**
* @return suffix for columns in the embedded value object. An empty {@link String} by default.
*/
String suffix() default "";

/**
* Load strategy to be used {@link Embedded#onEmpty()}.
*
Expand Down Expand Up @@ -104,6 +109,12 @@ enum OnEmpty {
*/
@AliasFor(annotation = Embedded.class, attribute = "prefix")
String prefix() default "";

/**
* @return suffix for columns in the embedded value object. An empty {@link String} by default.
*/
@AliasFor(annotation = Embedded.class, attribute = "suffix")
String suffix() default "";
}

/**
Expand Down Expand Up @@ -144,5 +155,11 @@ enum OnEmpty {
*/
@AliasFor(annotation = Embedded.class, attribute = "prefix")
String prefix() default "";

/**
* @return suffix for columns in the embedded value object. An empty {@link String} by default.
*/
@AliasFor(annotation = Embedded.class, attribute = "suffix")
String suffix() default "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,14 @@ public String withEmbeddedPrefix(String name) {
String embeddedPrefix = ownerProperty.getEmbeddedPrefix();
return embeddedPrefix + name;
}

public String withEmbeddedSuffix(String name) {

if (!ownerProperty.isEmbedded()) {
return name;
}

String embeddedSuffix = ownerProperty.getEmbeddedSuffix();
return name + embeddedSuffix;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,16 @@ public String getEmbeddedPrefix() {
return context.withEmbeddedPrefix(delegate.getEmbeddedPrefix());
}

@Override
public String getEmbeddedSuffix() {
return context.withEmbeddedSuffix(delegate.getEmbeddedSuffix());
}

@Override
public SqlIdentifier getColumnName() {
return delegate.getColumnName().transform(context::withEmbeddedPrefix);
return delegate.getColumnName()
.transform(context::withEmbeddedPrefix)
.transform(context::withEmbeddedSuffix);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ default String getEmbeddedPrefix() {
return "";
}

/**
* @return Suffix for embedded columns. If the column is not embedded the return value is empty.
*/
default String getEmbeddedSuffix() {
return "";
}

/**
* Returns whether an empty embedded object is supposed to be created for this property.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,33 +93,40 @@ void shouldEvaluateMappedCollectionExpressions() {
assertThat(property.getKeyColumn()).isEqualTo(quoted("key_col"));
}

@Test // DATAJDBC-111
@Test // DATAJDBC-111, GH-2303
void detectsEmbeddedEntity() {

final RelationalPersistentEntity<?> requiredPersistentEntity = context
.getRequiredPersistentEntity(DummyEntity.class);

SoftAssertions softly = new SoftAssertions();

BiConsumer<String, String> checkEmbedded = (name, prefix) -> {

BiConsumer<String, String[]> checkEmbedded = (name, args) -> {
String expectedPrefix = args[0];
String expectedSuffix = args[1];
RelationalPersistentProperty property = requiredPersistentEntity.getRequiredPersistentProperty(name);

if (!prefix.isEmpty()) {
if (!expectedPrefix.isEmpty() || !expectedSuffix.isEmpty()) {
softly.assertThat(property.isEmbedded()) //
.describedAs(name + " is embedded") //
.isTrue();
}

softly.assertThat(property.getEmbeddedPrefix()) //
.describedAs(name + " prefix") //
.isEqualTo(prefix);
.isEqualTo(expectedPrefix);

softly.assertThat(property.getEmbeddedSuffix()) //
.describedAs(name + " suffix") //
.isEqualTo(expectedSuffix);
};

checkEmbedded.accept("someList", "");
checkEmbedded.accept("id", "");
checkEmbedded.accept("embeddableEntity", "");
checkEmbedded.accept("prefixedEmbeddableEntity", "prefix");
checkEmbedded.accept("someList", new String[]{"", ""});
checkEmbedded.accept("id", new String[]{"", ""});
checkEmbedded.accept("embeddableEntity", new String[]{"", ""});

checkEmbedded.accept("prefixedEmbeddableEntity", new String[]{"prefix", ""});
checkEmbedded.accept("suffixedEmbeddableEntity", new String[]{"", "_suffixed"});

softly.assertAll();
}
Expand Down Expand Up @@ -190,6 +197,18 @@ void determineSequenceNameWithSchemaSpecified() {
.isEqualTo(SqlIdentifier.from(SqlIdentifier.quoted("public"), SqlIdentifier.quoted("my_seq")));
}

@Test // GH-2303
void detectsEmbeddedEntitySuffix() {
final RelationalPersistentEntity<?> requiredPersistentEntity = context
.getRequiredPersistentEntity(DummyEntity.class);

RelationalPersistentProperty property = requiredPersistentEntity
.getRequiredPersistentProperty("suffixedEmbeddableEntity");

assertThat(property.isEmbedded()).isTrue();
assertThat(property.getEmbeddedSuffix()).isEqualTo("_suffixed");
}

@SuppressWarnings("unused")
static class DummyEntity {

Expand Down Expand Up @@ -230,6 +249,8 @@ static class DummyEntity {
// DATAJDBC-111
private @Embedded(onEmpty = OnEmpty.USE_NULL, prefix = "prefix") EmbeddableEntity prefixedEmbeddableEntity;

private @Embedded(onEmpty = OnEmpty.USE_NULL, suffix = "_suffixed") EmbeddableEntity suffixedEmbeddableEntity;

public DummyEntity(Long id, SomeEnum someEnum, LocalDateTime localDateTime, ZonedDateTime zonedDateTime,
List<String> listOfString, String[] arrayOfString, List<OtherEntity> listOfEntity,
OtherEntity[] arrayOfEntity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void rootAggregatePathsGetCached() {
assertThat((Object) one).isSameAs(two);
}

@Test // GH-1586
@Test // GH-1586, GH-2303
void correctlyCascadesPrefix() {

RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(WithEmbedded.class);
Expand All @@ -102,8 +102,10 @@ void correctlyCascadesPrefix() {
RelationalPersistentProperty name = childEntity.getRequiredPersistentProperty("name");

assertThat(parent.getEmbeddedPrefix()).isEqualTo("prnt_");
assertThat(parent.getEmbeddedSuffix()).isEqualTo("_prnt");
assertThat(child.getEmbeddedPrefix()).isEqualTo("prnt_chld_");
assertThat(name.getColumnName()).isEqualTo(SqlIdentifier.quoted("PRNT_CHLD_NAME"));
assertThat(child.getEmbeddedSuffix()).isEqualTo("_chld_prnt");
assertThat(name.getColumnName()).isEqualTo(SqlIdentifier.quoted("PRNT_CHLD_NAME_CHLD_PRNT"));
}

@Test // GH-1657
Expand All @@ -125,7 +127,7 @@ static class EntityWithUuid {
}

static class WithEmbedded {
@Embedded.Empty(prefix = "prnt_") Parent parent;
@Embedded.Empty(prefix = "prnt_", suffix = "_prnt") Parent parent;
}

static class WithEmbeddedId {
Expand All @@ -138,7 +140,7 @@ private record CompositeId(int a, int b) {

static class Parent {

@Embedded.Empty(prefix = "chld_") Child child;
@Embedded.Empty(prefix = "chld_", suffix = "_chld") Child child;
}

static class Child {
Expand Down
Loading