Skip to content

Commit b7a2148

Browse files
committed
Don't try to write non-writeable properties.
Closes spring-projects#2230
1 parent 6ad449c commit b7a2148

File tree

7 files changed

+102
-7
lines changed

7 files changed

+102
-7
lines changed

src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ protected <T> T updateIndexedObject(T entity, IndexedObjectInformation indexedOb
465465
ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty();
466466

467467
// Only deal with text because ES generated Ids are strings!
468-
if (indexedObjectInformation.getId() != null && idProperty != null
468+
if (indexedObjectInformation.getId() != null && idProperty != null && idProperty.isWritable()
469469
&& idProperty.getType().isAssignableFrom(String.class)) {
470470
propertyAccessor.setProperty(idProperty, indexedObjectInformation.getId());
471471
}

src/main/java/org/springframework/data/elasticsearch/core/AbstractReactiveElasticsearchTemplate.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ protected <T> T updateIndexedObject(T entity, IndexedObjectInformation indexedOb
259259
ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty();
260260

261261
// Only deal with text because ES generated Ids are strings!
262-
if (indexedObjectInformation.getId() != null && idProperty != null
262+
if (indexedObjectInformation.getId() != null && idProperty != null && idProperty.isWritable()
263263
&& idProperty.getType().isAssignableFrom(String.class)) {
264264
propertyAccessor.setProperty(idProperty, indexedObjectInformation.getId());
265265
}

src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ private <R> R readEntity(ElasticsearchPersistentEntity<?> entity, Map<String, Ob
342342
PersistentPropertyAccessor<R> propertyAccessor = new ConvertingPropertyAccessor<>(
343343
targetEntity.getPropertyAccessor(result), conversionService);
344344
// Only deal with String because ES generated Ids are strings !
345-
if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) {
345+
if (idProperty != null && idProperty.isWritable() && idProperty.getType().isAssignableFrom(String.class)) {
346346
propertyAccessor.setProperty(idProperty, document.getId());
347347
}
348348
}
@@ -406,7 +406,7 @@ protected <R> R readProperties(ElasticsearchPersistentEntity<?> entity, R instan
406406

407407
for (ElasticsearchPersistentProperty prop : entity) {
408408

409-
if (entity.isCreatorArgument(prop) || !prop.isReadable()) {
409+
if (entity.isCreatorArgument(prop) || !prop.isReadable() || !prop.isWritable()) {
410410
continue;
411411
}
412412

src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchIntegrationTests.java

+48
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@
5454
import org.springframework.dao.DataAccessException;
5555
import org.springframework.dao.InvalidDataAccessApiUsageException;
5656
import org.springframework.dao.OptimisticLockingFailureException;
57+
import org.springframework.data.annotation.AccessType;
5758
import org.springframework.data.annotation.Id;
59+
import org.springframework.data.annotation.ReadOnlyProperty;
5860
import org.springframework.data.annotation.Version;
5961
import org.springframework.data.domain.PageRequest;
6062
import org.springframework.data.domain.Pageable;
@@ -3705,6 +3707,21 @@ public int hashCode() {
37053707
}
37063708
}
37073709

3710+
@Test // #2230
3711+
@DisplayName("should work with readonly id")
3712+
void shouldWorkWithReadonlyId() {
3713+
3714+
ReadonlyIdEntity entity = new ReadonlyIdEntity();
3715+
entity.setPart1("foo");
3716+
entity.setPart2("bar");
3717+
operations.save(entity);
3718+
3719+
ReadonlyIdEntity readEntity = operations.get(entity.getId(), ReadonlyIdEntity.class);
3720+
3721+
assertThat(readEntity.getPart1()).isEqualTo(entity.getPart1());
3722+
assertThat(readEntity.getPart2()).isEqualTo(entity.getPart2());
3723+
}
3724+
37083725
@Document(indexName = "#{@indexNameProvider.indexName()}")
37093726
private static class SampleEntityUUIDKeyed {
37103727
@Nullable
@@ -4450,5 +4467,36 @@ public String toString() {
44504467
+ '}';
44514468
}
44524469
}
4470+
4471+
@Document(indexName = "#{@indexNameProvider.indexName()}-readonly-id")
4472+
static class ReadonlyIdEntity {
4473+
@Field(type = FieldType.Keyword) private String part1;
4474+
4475+
@Field(type = FieldType.Keyword) private String part2;
4476+
4477+
@Id
4478+
@ReadOnlyProperty
4479+
@AccessType(AccessType.Type.PROPERTY)
4480+
public String getId() {
4481+
return part1 + '-' + part2;
4482+
}
4483+
4484+
public String getPart1() {
4485+
return part1;
4486+
}
4487+
4488+
public void setPart1(String part1) {
4489+
this.part1 = part1;
4490+
}
4491+
4492+
public String getPart2() {
4493+
return part2;
4494+
}
4495+
4496+
public void setPart2(String part2) {
4497+
this.part2 = part2;
4498+
}
4499+
}
4500+
44534501
// endregion
44544502
}

src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchIntegrationTests.java

+49
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@
5050
import org.springframework.beans.factory.annotation.Autowired;
5151
import org.springframework.dao.DataAccessException;
5252
import org.springframework.dao.OptimisticLockingFailureException;
53+
import org.springframework.data.annotation.AccessType;
5354
import org.springframework.data.annotation.Id;
55+
import org.springframework.data.annotation.ReadOnlyProperty;
5456
import org.springframework.data.annotation.Version;
5557
import org.springframework.data.domain.PageRequest;
5658
import org.springframework.data.domain.Pageable;
@@ -1161,6 +1163,23 @@ void shouldReturnMonoOfReactiveSearchHits() {
11611163
.verifyComplete();
11621164
}
11631165

1166+
@Test // #2230
1167+
@DisplayName("should work with readonly id")
1168+
void shouldWorkWithReadonlyId() {
1169+
1170+
ReadonlyIdEntity entity = new ReadonlyIdEntity();
1171+
entity.setPart1("foo");
1172+
entity.setPart2("bar");
1173+
1174+
operations.save(entity).block();
1175+
1176+
operations.get(entity.getId(), ReadonlyIdEntity.class) //
1177+
.as(StepVerifier::create) //
1178+
.assertNext(readEntity -> { //
1179+
assertThat(readEntity.getPart1()).isEqualTo(entity.getPart1()); //
1180+
assertThat(readEntity.getPart2()).isEqualTo(entity.getPart2()); //
1181+
}).verifyComplete();
1182+
}
11641183
// endregion
11651184

11661185
// region Helper functions
@@ -1494,5 +1513,35 @@ public String toString() {
14941513
+ seqNoPrimaryTerm + '}';
14951514
}
14961515
}
1516+
1517+
@Document(indexName = "#{@indexNameProvider.indexName()}-readonly-id")
1518+
static class ReadonlyIdEntity {
1519+
@Field(type = FieldType.Keyword) private String part1;
1520+
1521+
@Field(type = FieldType.Keyword) private String part2;
1522+
1523+
@Id
1524+
@ReadOnlyProperty
1525+
@AccessType(AccessType.Type.PROPERTY)
1526+
public String getId() {
1527+
return part1 + '-' + part2;
1528+
}
1529+
1530+
public String getPart1() {
1531+
return part1;
1532+
}
1533+
1534+
public void setPart1(String part1) {
1535+
this.part1 = part1;
1536+
}
1537+
1538+
public String getPart2() {
1539+
return part2;
1540+
}
1541+
1542+
public void setPart2(String part2) {
1543+
this.part2 = part2;
1544+
}
1545+
}
14971546
// endregion
14981547
}

src/test/java/org/springframework/data/elasticsearch/core/event/CallbackIntegrationTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static class SampleEntity {
241241
@Id private String id;
242242
@Nullable private String text;
243243

244-
@ReadOnlyProperty
244+
// @ReadOnlyProperty
245245
@Nullable private String className;
246246

247247
@Nullable

src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveCallbackIntegrationTests.java

-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.springframework.beans.factory.annotation.Autowired;
2828
import org.springframework.context.annotation.Configuration;
2929
import org.springframework.data.annotation.Id;
30-
import org.springframework.data.annotation.ReadOnlyProperty;
3130
import org.springframework.data.elasticsearch.annotations.Document;
3231
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
3332
import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
@@ -119,7 +118,6 @@ static class SampleEntity {
119118
@Id private String id;
120119
private String text;
121120

122-
@ReadOnlyProperty
123121
@Nullable private String className;
124122

125123
public SampleEntity(String id, String text) {

0 commit comments

Comments
 (0)