代码之家  ›  专栏  ›  技术社区  ›  Jcov

JPA OneToone更新而不是插入

  •  1
  • Jcov  · 技术社区  · 7 年前

    我是spring/jpa新手,我正在尝试使用database relationship@annotations来简化我的代码。

    我有两个实体,一个用户实体和令牌实体。 当对用户调用setToken()时,我希望该令牌覆盖表中与该用户关联的所有旧令牌。

    目前,新的令牌(通过user.setToken())正在插入而不是更新。

    我该如何实现这段关系?在“跛脚人”中…用户甚至只能拥有一个令牌,并且可以随时获得另一个令牌,丢弃旧令牌。 在这些模型中有一些额外的字段,为了清楚起见,我将其截断。

    @Entity
    @Table(name = "Users")
    public class User {
    
        @Column(name = "USER_ID")
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private Long userId;
    
        @OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
        @JoinColumn(name = "REFRESH_TOKEN_ID")
        private RefreshToken refreshToken;
    
    ...setters and getters
    

    以及代币代码:

    @Entity
    @Table(name = "RefreshTokens")
    public class RefreshToken {
    
        @Column(name = "REFRESH_TOKEN_ID")
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long tokenId;
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   MyTwoCents    7 年前

    如果你的 RefreshToken 只有一个字段 刷新令牌ID 很长。为什么你需要不同的桌子。你可以吃这样的东西

    public class User {
    
        @Column(name = "USER_ID")
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private Long userId;
    
        @Column(name = "REFRESH_TOKEN_ID")
        private Long refreshToken;
    
    ...
    

    什么时候? setToken() 你必须设置任何值。如果是的话就这样。你的逻辑很好,

    如果没有,则始终可以基于当前时间或其他内容在Java中生成唯一值。

    如果你想继续使用同样的模式 orphanRemoval = true

    @OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "REFRESH_TOKEN_ID")
    private RefreshToken refreshToken;
    
        2
  •  0
  •   Ilias Mentz    7 年前

    永远不要修改实体的主键

    这是不可能的,因为你改变了令牌的ID。您需要在RefreshToken中创建一个不同的ID,该ID是唯一的,保存后保持不变。

    如果你真的需要-你最好删除实体并创建一个新的实体,这个实体只复制旧的实体,但是有一个新的主键。