Собственность населения с помощью методов 'Wherher' - PullRequest
0 голосов
/ 15 января 2019

Свойство Население не работает должным образом для меня при использовании неизменяемых объектов.

Я пытаюсь следовать разделу Property Population справочного документа spring-data-couchbase-3.1.4.RELEASE , который предполагает, что его я могу передать в неизменяемом объект с подходящим @wither методом для установки идентификатора. Однако, когда я попытался это сделать, у возвращенного объекта все еще есть значение null для идентификатора.

ком / пример / demospringdatacouchbaseapp / модель / Car.java

import static org.springframework.data.couchbase.core.mapping.id.GenerationStrategy.USE_ATTRIBUTES;
import org.springframework.data.couchbase.core.mapping.Document;
import org.springframework.data.couchbase.core.mapping.id.GeneratedValue;
import org.springframework.data.couchbase.core.mapping.id.IdAttribute;
import com.couchbase.client.java.repository.annotation.Field;
import com.couchbase.client.java.repository.annotation.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Value;
import lombok.experimental.Wither;

@Value
@AllArgsConstructor
@Builder(toBuilder=true)
@Document
public class Car {

  public static final String ID_DELIMITER = ".";

  @Id
  @GeneratedValue(strategy = USE_ATTRIBUTES, delimiter = ID_DELIMITER)
  @Wither
  String id;

  @Field
  @IdAttribute(order=0)
  String manufacturer;

  @Field
  @IdAttribute(order=1)
  String model;

  @Field
  @IdAttribute(order=2)
  String spec;

  @Field
  String colour;

}

ком / пример / demospringdatacouchbaseapp / хранилище / CarRepository.java

import java.util.Collection;
import org.springframework.data.couchbase.repository.CouchbaseRepository;
import com.example.demospringdatacouchbaseapp.model.Car;

public interface CarRepository extends CouchbaseRepository<Car, String> {

  Collection<Car> findByColour(String colour);

}

Создать простой автомобильный тест

  @Test
  public void createSingCarTest() {

    /*
     * Given
     */

    Car givenCar = createMadWeeClio();

    /*
     * When
     */

    Car persistedCar = repository.save(givenCar);

    /*
     * Then
     */

    assertThat(persistedCar).isEqualTo(givenCar.withId(getExpectedId(givenCar)));

  }

  ...

  private String getExpectedId(Car givenCar) {
    return givenCar.getManufacturer() + Car.ID_DELIMITER + givenCar.getModel() + Car.ID_DELIMITER
        + givenCar.getSpec();
  }

  private Car withExpectedId(Car car) {
    return car.withId(getExpectedId(car));
  }

  private Car createMadWeeClio() {
    return Car.builder().manufacturer("RenaultSport").model("Clio").spec("200 Cup").colour("white")
        .build();
  }

  private Car createMadMeg() {
    return Car.builder().manufacturer("RenaultSport").model("Megane").spec("R.S Trophy")
        .colour("Yellow").build();
  }

Я ожидал, что операция CouchbaseRepository::save вернет новый экземпляр моего неизменяемого объекта сущности с заполненным автоматически сгенерированным свойством ID. Однако в моих тестах он возвращается как null.

Передача изменчивой сущности приводит к тому, что поле id устанавливается в соответствии с ожиданиями. Я также вижу, как поле ID заполняется в базе данных.

1 Ответ

0 голосов
/ 16 января 2019

Я думаю, что проблема в том, что операция save не создает новый экземпляр вашего Car объекта - скорее он попытается установить идентификатор объекта (но не может, поскольку он неизменен).

Аннотация @Value Lombok приводит к методу, который выглядит как

Car withId(String id) {
    return new Car(id, this.model, this.spec, this.colour);
}

но этот метод не вызывается при save вашем объекте.

При извлечении объекта из базы данных вызывается метод withId. Поэтому, если вы вернете все объекты из базы данных (или выполните поиск по другим критериям, например, модели), вы увидите, что они действительно имеют свойства id со значениями. Документация охватывает это здесь:

https://docs.spring.io/spring-data/couchbase/docs/3.1.4.RELEASE/reference/html/#mapping.property-population

...