一对多关系和ID生成

问题描述 投票:0回答:2

我有两节课。

民意调查.java

public class Poll {
    @Id
    @Column(name = "poll_id")
    String pollId;
    String question;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    String endDateTime;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "poll_id_fk", referencedColumnName = "poll_id")
    List<Choice> choices;
}

选择.java

public class Choice {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "choice_id")
    Long choiceId;
    String text;
    Integer votes;
}

当我创建新的民意调查时, choice_id 会从之前创建的最后一个 choice_id 的编号开始递增。创建新民意调查时,如何使 choice_id 重置其值?

我尝试更改 GenerationType 策略,但这似乎没有任何影响。我期待这样的结果:

[
    {
        "pollId": "MvWRj",
        "question": "poll 2?",
        "endDateTime": "2023-07-09 19:50",
        "choices": [
            {
                **"choiceId": 1,**
                "text": "choice 1",
                "votes": 1
            },
            {
                **"choiceId": 2,**
                "text": "choice 2",
                "votes": 0
            }
        ]
    },
    {
        "pollId": "V838D",
        "question": "poll 1?",
        "endDateTime": "2023-07-09 19:50",
        "choices": [
            {
                **"choiceId": 1,**
                "text": "choice 1",
                "votes": 1
            },
            {
                **"choiceId": 2,**
                "text": "choice 2",
                "votes": 0
            }
        ]
    }
]

而我得到的结果如下:

[
    {
        "pollId": "MvWRj",
        "question": "poll 2?",
        "endDateTime": "2023-07-09 19:50",
        "choices": [
            {
                **"choiceId": 3,**
                "text": "choice 1",
                "votes": 1
            },
            {
                **"choiceId": 4,**
                "text": "choice 2",
                "votes": 0
            }
        ]
    },
    {
        "pollId": "V838D",
        "question": "poll 1?",
        "endDateTime": "2023-07-09 19:50",
        "choices": [
            {
                **"choiceId": 1,**
                "text": "choice 1",
                "votes": 1
            },
            {
                **"choiceId": 2,**
                "text": "choice 2",
                "votes": 0
            }
        ]
    }
]
java spring one-to-many
2个回答
0
投票

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

@Lob
@Column
private List<Choice> choices = new ArrayList<>();

不需要让类选择一个实体,也不需要有 Id,因为你已经索引了集合。


0
投票

为了实现您正在寻找的行为(其中

choiceId
会针对每个新的
Poll
进行重置),您将需要对当前的实现进行一些更改。主要问题是
@GeneratedValue(strategy = GenerationType.AUTO)
类中的
Choice
为所有
Choice
实体中的每个
Poll
实体生成唯一标识符,从而导致不同民意调查中的 ID 不断增加。

以下是您可以考虑的一些方法:

1.手动ID管理

您可以手动管理

choiceId
而不是使用
@GeneratedValue
。此方法要求您在创建或向投票添加选项时,为每个
choiceId
相对于其
Choice
设置
Poll
。然而,这可能会变得复杂且容易出错,尤其是对于并发事务。

2.复合键

考虑使用包含

pollId
和每个选项的附加标识符的复合键。这样,
choiceId
只能在每个
Poll
的范围内是唯一的。组合键可以使用 JPA 中的
@Embeddable
@EmbeddedId
来实现。

复合键类示例:

@Embeddable
public class ChoiceId implements Serializable {
    private String pollId;
    private Long choiceNumber; // This resets for each Poll

    // getters, setters, hashCode, equals
}

在您的

Choice
课程中,您将使用
ChoiceId
作为主键。

3.数据库级解决方案

如果您的数据库支持,您可以使用特定于数据库的功能,该功能允许根据条件重置序列号(例如创建新的

Poll
)。这是特定于数据库的,可能无法跨不同的数据库系统移植。

4.在民意调查中使用计数器

Poll
实体中添加一个计数器,用于跟踪选择的数量。每次添加新选择时,都会增加此计数器并将其用作
choiceId
。这可确保
choiceId
每次民意调查都是唯一的,但会针对每个新民意调查重置。

5.业务逻辑层

在服务层或业务逻辑层处理

choiceId
生成,您可以在其中更好地控制 ID 生成逻辑。这将涉及根据特定民意调查的现有选择计算下一个
choiceId

选择正确的方法

每种方法在复杂性、易于实施性和可维护性方面都有其权衡。最佳方法取决于您的具体要求和应用程序运行的环境。

例如,如果您想让事情保持简单并避免修改数据库架构,则手动 ID 管理或在业务逻辑层处理它可能是可行的方法。另一方面,如果您需要一个更强大且可扩展的解决方案,那么考虑组合键或数据库级解决方案可能更合适。

© www.soinside.com 2019 - 2024. All rights reserved.