spring 一对多关系和ID生成

bprjcwpo  于 2024-01-05  发布在  Spring
关注(0)|答案(2)|浏览(139)

我有两节课。
Poll.java

  1. public class Poll {
  2. @Id
  3. @Column(name = "poll_id")
  4. String pollId;
  5. String question;
  6. @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
  7. String endDateTime;
  8. @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
  9. @JoinColumn(name = "poll_id_fk", referencedColumnName = "poll_id")
  10. List<Choice> choices;
  11. }

字符串

Choice.java

  1. public class Choice {
  2. @Id
  3. @GeneratedValue(strategy = GenerationType.AUTO)
  4. @Column(name = "choice_id")
  5. Long choiceId;
  6. String text;
  7. Integer votes;
  8. }


当我创建新的投票时,choice_id会从上次创建的choice_id的编号开始递增。当创建新的投票时,如何使choice_id重置其值?
我尝试改变策略GenerationType,但这似乎并不影响任何东西.我期待这样的结果:

  1. [
  2. {
  3. "pollId": "MvWRj",
  4. "question": "poll 2?",
  5. "endDateTime": "2023-07-09 19:50",
  6. "choices": [
  7. {
  8. **"choiceId": 1,**
  9. "text": "choice 1",
  10. "votes": 1
  11. },
  12. {
  13. **"choiceId": 2,**
  14. "text": "choice 2",
  15. "votes": 0
  16. }
  17. ]
  18. },
  19. {
  20. "pollId": "V838D",
  21. "question": "poll 1?",
  22. "endDateTime": "2023-07-09 19:50",
  23. "choices": [
  24. {
  25. **"choiceId": 1,**
  26. "text": "choice 1",
  27. "votes": 1
  28. },
  29. {
  30. **"choiceId": 2,**
  31. "text": "choice 2",
  32. "votes": 0
  33. }
  34. ]
  35. }
  36. ]


而我得到的结果是这样的:

  1. [
  2. {
  3. "pollId": "MvWRj",
  4. "question": "poll 2?",
  5. "endDateTime": "2023-07-09 19:50",
  6. "choices": [
  7. {
  8. **"choiceId": 3,**
  9. "text": "choice 1",
  10. "votes": 1
  11. },
  12. {
  13. **"choiceId": 4,**
  14. "text": "choice 2",
  15. "votes": 0
  16. }
  17. ]
  18. },
  19. {
  20. "pollId": "V838D",
  21. "question": "poll 1?",
  22. "endDateTime": "2023-07-09 19:50",
  23. "choices": [
  24. {
  25. **"choiceId": 1,**
  26. "text": "choice 1",
  27. "votes": 1
  28. },
  29. {
  30. **"choiceId": 2,**
  31. "text": "choice 2",
  32. "votes": 0
  33. }
  34. ]
  35. }
  36. ]

jvidinwx

jvidinwx1#

要实现您所期望的行为(choiceId会为每个新的Poll重置),您需要对当前实现进行一些更改。主要问题是Choice类中的@GeneratedValue(strategy = GenerationType.AUTO)为所有Poll实体中的每个Choice实体生成唯一标识符,从而导致不同轮询中的ID递增。
以下是您可以考虑的几种方法:

1.手动ID管理

您可以手动管理choiceId,而不是使用@GeneratedValue。这种方法需要您在创建或向投票添加选项时,相对于Poll为每个Choice设置choiceId。然而,这可能会变得复杂且容易出错,特别是在并发事务中。

2.复合密钥

考虑使用一个复合键,它包含pollId和每个选项的附加标识符。这样,choiceId只能在每个Poll的范围内是唯一的。复合键可以在JPA中使用@Embeddable@EmbeddedId实现。
复合键类的示例:

  1. @Embeddable
  2. public class ChoiceId implements Serializable {
  3. private String pollId;
  4. private Long choiceNumber; // This resets for each Poll
  5. // getters, setters, hashCode, equals
  6. }

字符串
Choice类中,可以使用ChoiceId作为主键。

3.数据库级解决方案

如果您的数据库支持它,您可以使用特定于数据库的功能,该功能允许基于条件重置序列号(例如创建新的Poll)。这是特定于数据库的,可能无法跨不同的数据库系统移植。

4.轮询中使用计数器

Poll实体中添加一个计数器,用于跟踪选择的数量。每次添加新的选择时,递增此计数器并将其用作choiceId。这将确保choiceId在每次轮询时都是唯一的,但在每次新的轮询时都会重置。

5.业务逻辑层

在服务层或业务逻辑层处理choiceId的生成,在那里您可以对ID生成逻辑进行更多的控制。这将涉及根据特定轮询的现有选择计算下一个choiceId

选择正确的方法

这些方法在复杂性、易实现性和可维护性方面都有其优缺点,最佳方法取决于您的特定需求和应用程序运行的环境。
例如,如果您想保持简单并避免修改数据库模式,则手动ID管理或在业务逻辑层处理它可能是一种方法。另一方面,如果您需要一个更强大的解决方案,可以很好地扩展,考虑组合键或数据库级解决方案可能更合适。

展开查看全部
cygmwpex

cygmwpex2#

关系数据库就是这样工作的。每个记录的ID必须是唯一的,以区分它们。但是,如果想只存储与您的投票相关的集合,您可以尝试这种设置字段的方式。

  1. @Lob
  2. @Column
  3. private List<Choice> choices = new ArrayList<>();

字符串
不需要创建类Choise一个Entity,也不需要有Id,因为你有索引集合。

相关问题