spring 一对多关系和ID生成

bprjcwpo  于 5个月前  发布在  Spring
关注(0)|答案(2)|浏览(41)

我有两节课。
Poll.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;
}

字符串

Choice.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
            }
        ]
    }
]

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实现。
复合键类的示例:

@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管理或在业务逻辑层处理它可能是一种方法。另一方面,如果您需要一个更强大的解决方案,可以很好地扩展,考虑组合键或数据库级解决方案可能更合适。

cygmwpex

cygmwpex2#

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

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

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

相关问题