首页 > 解决方案 > 保存后的 JPA 查询不返回数据库生成的字段

问题描述

我正在尝试将此模型保存到数据库中,然后检索我刚刚保存的内容。除了数据库生成的 UUID 字段外,每个字段都会被检索。

@Entity
@Table(name = "usertoken")
public class UserToken implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "token", insertable = false, updatable = false, nullable = false)
    private UUID token;
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="usersid", nullable=false)
    private User user;
    
    @Column(name = "expiration", updatable = false, nullable = false)
    private LocalDateTime expiration;

我从服务中保存令牌

token = tokenRepository.save(token);

生成此 SQL

Hibernate: 
    insert 
    into
        usertoken
        (expiration, usersid) 
    values
        (?, ?)

下一条语句获取令牌

token = tokenRepository.findByUser(user);

我看到 SQL 选择包括令牌字段

Hibernate: 
    select
        usertoken0_.id as id1_8_,
        usertoken0_.expiration as expirati2_8_,
        usertoken0_.token as token3_8_,
        usertoken0_.usersid as usersid4_8_ 
    from
        usertoken usertoken0_ 
    where
        usertoken0_.usersid=?

...但返回的对象填充了每个字段但令牌。数据库确实在令牌列中有一个值。我不知道为什么它会填充除一个之外的每个字段。这是有问题的表格:

CREATE TABLE public.usertoken
(
    id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    usersid integer NOT NULL,
    token uuid NOT NULL DEFAULT uuid_generate_v1(),
    expiration timestamp without time zone NOT NULL,
    CONSTRAINT "usertoken_pkey" PRIMARY KEY (id)
)

当我稍后查询找到令牌并且正确填充了 UUID 字段时,我忘记添加了。那么 JPA 缓存有什么奇怪的地方吗?插入后休眠是否忽略数据库DEFAULT列值?

tokenRepository.findByToken(UUID.fromString(userToken));

Hibernate: 
    select
        usertoken0_.id as id1_8_,
        usertoken0_.expiration as expirati2_8_,
        usertoken0_.token as token3_8_,
        usertoken0_.usersid as usersid4_8_ 
    from
        usertoken usertoken0_ 
    where
        usertoken0_.token=?

标签: springpostgresqlhibernatejpa

解决方案


  • 您必须向休眠发出信号,表明数据库正在生成该字段。所以添加以下内容:
    @org.hibernate.annotations.Generated(value = GenerationTime.INSERT)
    @Column(name = "token", insertable = false, 
            updatable = false, nullable = false)
    private UUID token;
  • 您还将select在之后看到仅针对该列的休眠问题insert

推荐阅读