Собственность населения с помощью методов 'Wherher'

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

Я пытаюсь следовать разделу 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 устанавливается в соответствии с ожиданиями. Я также вижу, как поле идентификатора заполняется в базе данных.

1 ответ

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

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

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/

Другие вопросы по тегам