保存后无法获取数据库生成值

Ale*_*lic 4 postgresql hibernate jpa spring-data-jpa spring-boot

我正在使用 SpringBoot、Spring 数据和 postgresql。

在 postgres 中,我创建了一张表。

CREATE EXTENSION "uuid-ossp";
CREATE TABLE user (
    id serial PRIMARY KEY not null,          
    user_id varchar(255) not null default uuid_generate_v4()
);   
Run Code Online (Sandbox Code Playgroud)

比创建实体

@Entity
public class User implements Serializable {

  private static final long serialVersionUID = 9129894781337596497L;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(columnDefinition = "serial")
  private Integer id;

  @Column(insertable = false)
  private String userId;

  public static User create(){
    User user = new User();
    return user;
  }

  public String getUserId(){
    return userId;
  }

}
Run Code Online (Sandbox Code Playgroud)

比这样创建 jpa 存储库

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {}
Run Code Online (Sandbox Code Playgroud)

当我保存用户时,我需要获取 id 和 userId 但我得到的是 null 并且在数据库中生成了 UUID。

User user = userRepository.save(User.create());
assertThat(user.getUserId()).isNotNull();
Run Code Online (Sandbox Code Playgroud)

如何从数据库中获取这些生成的值?

ris*_*kop 5

您必须重新读取插入的实体或(自 Hibernate 3.2 以来?)您可以在列上指定 @Generated(GenerationTime.INSERT) (https://docs.jboss.org/hibernate/orm/5.0/topical/html/ generate/GeneratedValues.html#_legacy_support_in_database_generation ),这会导致 hibernate 在插入后重新读取属性值。

我创建了一个小演示:

http://peter.risko.hu/java_incubator/spring_data_postgres_uuid.zip

用户实体:

@Id
@SequenceGenerator(name="seq", sequenceName="seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seq")
@Column(columnDefinition = "serial")
private Integer id;

@Column(insertable = false, name="user_id")
private String userId;

public String getUserId(){
    return userId;
}

public static User create(){
    User user = new User();
    log.info("user created in memory: " + user);
    return user;
}

public Integer getId(){
    return id;
}

@Override
public String toString() {
    return "[id: " + id + ", userId: " + userId + "]";
}
Run Code Online (Sandbox Code Playgroud)

考试:

@Test
public void testInsert() {
    User u = userRepository.save(User.create());
    log.info("user after save: " + u);
    log.info("users queried from db: " + userRepository.findAll());
}
Run Code Online (Sandbox Code Playgroud)

输出:

tst.User - user created in memory: [id: null, userId: null]
tst.UserRepositoryTest - user after save: [id: 960, userId: null]
tst.UserRepositoryTest - users queried from db: [[id: 960, userId: dc7cdc53-984d-4051-a3f3-ecc7136d9fd8]]
Run Code Online (Sandbox Code Playgroud)

如果我应用@Generated(GenerationTime.INSERT):

@Column(insertable = false, name="user_id")
@Generated(GenerationTime.INSERT)
private String userId;
Run Code Online (Sandbox Code Playgroud)

那么结果是:

tst.User - user created in memory: [id: null, userId: null]
tst.UserRepositoryTest - user after save: [id: 961, userId: c68ea300-2f20-47ea-a76d-6e1aaf97a5ea]
tst.UserRepositoryTest - users queried from db: [[id: 960, userId: dc7cdc53-984d-4051-a3f3-ecc7136d9fd8], [id: 961, userId: c68ea300-2f20-47ea-a76d-6e1aaf97a5ea]]
Run Code Online (Sandbox Code Playgroud)