【问题标题】:How to automatically generate id from 1 with JPA?如何使用 JPA 从 1 自动生成 id?
【发布时间】:2018-06-22 02:34:13
【问题描述】:

我正在开发其他 Web 服务。我发现使用 JPA 和 Spring Boot 自动生成的 Id 存在一些问题。
以下是模型:

@Entity
public class Post {    
    @Id @GeneratedValue
    private Long id;

    private String postText;    
    @ManyToOne
    private BlogUser user;    
    private LocalDateTime createdDate;
}

@Entity
public class Comment {    
    @Id @GeneratedValue
    private Long id;    
    private String commentText;

保存对象如下所示:

    Post firstPost = Post.builder()
            .postText("First post !!! UUUUUhuuuuu!")
            .user(carlos)
            .createdDate(LocalDateTime.now())
            .build();
    Post secondPost = Post.builder()
            .postText("I like this blog posting so much :)")
            .user(carlos)
            .createdDate(LocalDateTime.now())
            .build();
    Post thirdPost = Post.builder()
            .postText("To be or not to be? What is the question.")
            .user(carlos)
            .createdDate(LocalDateTime.now())
            .build();

    postService.addPost(firstPost);
    postService.addPost(secondPost);
    postService.addPost(thirdPost);

    BlogUser sailor = BlogUser.builder()
            .userName("sailor").password("123").email("sailor@gmail.com").build();
    userService.addUser(sailor);

    Comment commentToFirstPost = Comment.builder().commentText("you an idiot!")
            .user(sailor).post(firstPost).createdDate(LocalDateTime.now()).build();
    Comment secondCommentToFirstPost = Comment.builder().commentText("You should sail to Antarctica!")
            .user(sailor).post(firstPost).createdDate(LocalDateTime.now()).build();

但是,之后我在数据库中有实例:

  • 帖子:
    1 第一篇文章
    2 第二个帖子
    3 第三篇文章

  • 评论:
    4 第一条评论
    5秒评论

我想从1 进行 cmets 迭代,因为它完全是另一个类。与帖子无关。应该是这样的:

1 第一条评论
2 第二条评论

更新:

数据库是 PostgreSQL。另外,我很想知道如何为 MySQL 做这件事。

如何解决这个问题?

【问题讨论】:

  • 什么是数据库?
  • @MaciejKowalski 问题已更新
  • 这取决于您的 JPA 提供者而不是数据库,因为您的提供者似乎对两个实体使用相同的序列“对象”。

标签: java database spring spring-boot jpa


【解决方案1】:

当您使用原版@GeneratedValue 时,其设置为javax.persistence.GenerationType.AUTO,其中:

表明持久性提供者应该选择一个合适的 特定数据库的策略。

在大多数情况下,实际上是GenerationType.SEQUENCE

在这种情况下,hibernate 将使用它的内部序列来使用像你这样的普通/香草风格注释的字段。

这说明计数器不会为每个实体重新启动,因为那里使用了相同的序列。

您可以尝试强制生成本机 id:

@GeneratedValue(strategy = GenerationType.IDENTITY)

【讨论】:

    【解决方案2】:

    做这样的事情:

    public class Post 
    {
        @Id
        @SequenceGenerator(name="seq",sequenceName="my_seq")        
        @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")               
        private Integer id;
    }
    

    对每个实体使用不同的顺序。

    【讨论】:

      【解决方案3】:

      使用TableGeneratorinitialValue属性

        @Id
        @TableGenerator(name = "COMMENT_GEN",
                        table = "id_gen",
                        pkColumnName = "seq_name",
                        valueColumnName = "seq_number",
                        initialValue = 1)
        @GeneratedValue(strategy = GenerationType.TABLE, generator = "COMMENT_GEN")
        private Long id; 
      

      【讨论】:

      • 你能解释一下它应该如何解决这个问题吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-25
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多