簡體   English   中英

Spring JPA Crud Repository Save不返回UUID字段

[英]Spring JPA Crud Repository Save Not Returning UUID Field

我試圖用純JPA保存實體,並且保存時不返回Postgres UUID字段。 默認情況下,使用public.uuid_generate_v1mc()自動生成UUID字段。 我使用postgres作為數據庫,由於某種原因,在jpa中進行保存時創建的默認值不會被返回。 我嘗試添加一個@Generated字段並將其設置為auto並且不執行任何操作。

難道我做錯了什么?

數據庫創建語句

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
);

實體

@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;
    }
}

基本實體

@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"
}

您需要在將由數據庫生成的字段上添加@Generated注釋。

@Generated(GenerationTime.ALWAYS)
private UUID uuid;

說明

您需要找到一種方法來告訴JPA提供者(1)在數據庫端生成的字段和(2)何時獲取它們。

對於這樣的屬性,有一個名為@Generated的注釋,它提供了兩個選項:

  • 在insert( GenerationTime.INSERT )上獲取生成的屬性;
  • 在插入和更新( GenerationTime.ALWAYS )上獲取生成的屬性。

要檢索所需的@Generated值,Hibernate(Spring將其用作默認的JPA提供程序)將執行另一個SELECT語句。

我不知道你要使用PUT端點(創建/更新/覆蓋資源1 ),但是我會選擇@Generated(ALWAYS)因為使用@Generated(INSERT) ,你將獲得null更新/合並。

獎金

我發現這個視頻非常有用,而且非常重要。

視頻


1 在這里認真討論

所以我發現你必須使用注釋@Generated(GenerationTime.INSERT)

我實際上正在使用@GeneratedValue,我嘗試了所有不同的值,但沒有一個工作。 最后在使用@Generated(GenerationTime.INSERT)后,它工作正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM