Весенний репозиторий JPA Crud Сохранить, не возвращая Поле UUID - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь сохранить объект с чистым JPA, и поле Postgres UUID не возвращается при сохранении.Поле UUID генерируется автоматически по умолчанию с использованием public.uuid_generate_v1mc().Я использую postgres в качестве базы данных, и по какой-то причине значение по умолчанию, которое создается при сохранении в jpa, не возвращается.Я попытался добавить поле @Generated и установить его в авто, и это ничего не делает.

Я что-то не так делаю?

Оператор создания базы данных

CREATE TABLE usermgmt.test
(
  id SERIAL PRIMARY KEY,
  active boolean NOT NULL DEFAULT false,
  created timestamp without time zone NOT NULL DEFAULT now(),
  updated timestamp without time zone NOT NULL DEFAULT now(),
  description character varying,
  name character varying NOT NULL,
  external_id bigint UNIQUE ,
  uuid uuid DEFAULT public.uuid_generate_v1mc(),
  alias character varying NOT NULL UNIQUE,
  code character varying NOT NULL UNIQUE
);

Entity

@SuppressWarnings("serial")
@Entity(name = "managementTest")
@Cacheable
@Table(schema = "usermgmt", name = "test")
public class Test extends BaseEntity implements Serializable {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String description;

    @Column(nullable = false, insertable = false, updatable = false)
    private UUID uuid;

    @Column(nullable = false, unique = true)
    private String alias;

    @Column(nullable = false, unique = true)
    private String code;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return
     */
    public String getDescription() {
        return description;
    }

    /**
     * @param description
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * @return the uuid
     */
    public UUID getUuid() {
        return uuid;
    }

    public void setUuid(UUID uuid) {
        this.uuid = uuid;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

Base Entity

@MappedSuperclass
public abstract class BaseEntity {
    private LocalDateTime created;
    private LocalDateTime updated;
    @NotNull
    private Boolean active;

    public BaseEntity() {
        this.active = Boolean.TRUE;
    }

    @PrePersist
    @PreUpdate
    void setDates() {
        if (this.created == null) {
            this.created = LocalDateTime.now();
        }

        this.updated = LocalDateTime.now();
    }

    public Boolean getActive() {
        return this.active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    public LocalDateTime getCreated() {
        return this.created;
    }

    public LocalDateTime getUpdated() {
        return this.updated;
    }

    public void setUpdated(LocalDateTime updated) {
        this.updated = updated;
    }

    public void touch() {
        this.updated = LocalDateTime.now();
    }
}

Crud

@Repository("managementTestCrudRepository")
public interface TestCrudRepository extends JpaRepository<Test, Long> {
    Test findByCode(String code);
    Test findByUuid(UUID uuid);
    Test findByAlias(String alias);
    List<Test> findByActive(Boolean active);
}

Этот метод я использовал для сохранения сущности

@PutMapping
public Test putByJson(@RequestBody String json) {
    return testCrudRepository.save(new Gson().fromJson(json, Test.class));
}

Объект, возвращаемый почтальоном

{
    "created": {
        "month": "OCTOBER",
        "year": 2018,
        "dayOfYear": 275,
        "hour": 11,
        "minute": 9,
        "nano": 325000000,
        "second": 52,
        "dayOfMonth": 2,
        "dayOfWeek": "TUESDAY",
        "monthValue": 10,
        "chronology": {
            "id": "ISO",
            "calendarType": "iso8601"
        }
    },
    "updated": {
        "month": "OCTOBER",
        "year": 2018,
        "dayOfYear": 275,
        "hour": 11,
        "minute": 9,
        "nano": 329000000,
        "second": 52,
        "dayOfMonth": 2,
        "dayOfWeek": "TUESDAY",
        "monthValue": 10,
        "chronology": {
            "id": "ISO",
            "calendarType": "iso8601"
        }
    },
    "active": true,
    "id": 2,
    "externalId": null,
    "name": "test1",
    "description": "test1",
    "uuid": null,
    "alias": "test1",
    "code": "test1"
}

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Решение

Вам необходимо добавить аннотацию @Generated над полями, которые будут сгенерированы базой данных.

@Generated(GenerationTime.ALWAYS)
private UUID uuid;

Объяснение

Вам необходимо найти способ сообщить своему провайдеру JPA о (1) полях, которые генерируются на стороне базы данных, и (2) когда их нужно извлекать.

Для таких свойств существует аннотация под названием @Generated, которая предоставляет две опции:

  • для извлечения сгенерированного свойства при вставке (GenerationTime.INSERT);
  • для извлечения сгенерированного свойства как при вставке, так и при обновлении (GenerationTime.ALWAYS).

Чтобы получить необходимые значения @Generated, Hibernate (Spring использует его в качестве поставщика JPA по умолчанию) выполнит дополнительный оператор SELECT.

Я не знаю, для чего вы собираетесь использовать конечную точку PUT (создать / обновить / переопределить ресурс 1 ), ноЯ бы выбрал @Generated(ALWAYS), поскольку с @Generated(INSERT) вы получите null при обновлении / слиянии.

Бонус

Я считаю это видео очень информативным и актуальным.

video


1 серьезное обсуждение здесь

0 голосов
/ 10 октября 2018

Итак, я обнаружил, что вы должны использовать аннотацию @Generated (GenerationTime.INSERT)

Я на самом деле использовал @GeneratedValue, и я попробовал все разные значения для этого, и ни одно из них не сработало.Наконец, после использования @Generated (GenerationTime.INSERT) все заработало нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...