gpt4 book ai didi

mysql - Mysql 自动生成的 PK 用于另一个表和 JPA 的问题

转载 作者:行者123 更新时间:2023-11-29 09:00:07 28 4
gpt4 key购买 nike

我的用例如下:我使用 MySQL 和 JPA 2,并且有两个实体:通过 OneToMany 关系关联的 OrderLineItem

我希望 GUI 层能够同时保留 Order 和 LineItem。

考虑到Order的PK是由MySQL自动生成的,并且是LineItem PK的一部分,我不知道如何检索生成的订购 PK 以便将其用于同一交易中的 LineItem PK。

有人可以帮忙吗?

根据您的反馈,这里是来自实体的一些示例代码(我实际上编写了上面的用例/域。我的更复杂,因此您不会看到任何订单或 LineItem)。

@Entity
@Table(name = "advertisement")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "status_need_ID", discriminatorType = DiscriminatorType.INTEGER)
@NamedQueries({
@NamedQuery(name = "Advertisement.findAll", query = "SELECT a FROM Advertisement a"),
@NamedQuery(name = "Advertisement.findByAdvertisementID", query = "SELECT a FROM Advertisement a WHERE a.advertisementID = :advertisementID"),
@NamedQuery(name = "Advertisement.findByAdvertisementTitle", query = "SELECT a FROM Advertisement a WHERE a.advertisementTitle = :advertisementTitle"),
@NamedQuery(name = "Advertisement.findByAdvertisementCreationDate", query = "SELECT a FROM Advertisement a WHERE a.advertisementCreationDate = :advertisementCreationDate"),
@NamedQuery(name = "Advertisement.findByStatusneedID", query = "SELECT a FROM Advertisement a WHERE a.statusneedID = :statusneedID")})
public class Advertisement implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "advertisement_ID", nullable = false)
private Integer advertisementID;
@Basic(optional = false)
@Column(name = "advertisement_title", nullable = false, length = 200)
private String advertisementTitle;
@Column(name = "advertisement_creation_date")
@Temporal(TemporalType.TIMESTAMP)
private Date advertisementCreationDate;
@Basic(optional = false)
@Lob
@Column(name = "advertisement_body", nullable = false, length = 2147483647)
private String advertisementBody;
@Column(name = "status_need_ID")
private Integer statusneedID;
@JoinTable(name = "postcode_to_advertisement_join", joinColumns = {
@JoinColumn(name = "advertisement_ID", referencedColumnName = "advertisement_ID", nullable = false)}, inverseJoinColumns = {
@JoinColumn(name = "postcode_ID", referencedColumnName = "postcode_ID", nullable = false)})
@ManyToMany
private Collection<Postcode> postcodeCollection;
@JoinTable(name = "advertisement_to_duration_join", joinColumns = {
@JoinColumn(name = "advertisement_ID", referencedColumnName = "advertisement_ID", nullable = false)}, inverseJoinColumns = {
@JoinColumn(name = "duration_ID", referencedColumnName = "duration_ID", nullable = false)})
@ManyToMany
private Collection<Duration> durationCollection;
@JoinTable(name = "full_or_part_time_basis_to_advertisement_join", joinColumns = {
@JoinColumn(name = "advertisement_ID", referencedColumnName = "advertisement_ID", nullable = false)}, inverseJoinColumns = {
@JoinColumn(name = "full_or_part_time_basis_ID", referencedColumnName = "full_or_part_time_basis_ID", nullable = false)})
@ManyToMany
private Collection<FullOrPartTimeBasis> fullOrPartTimeBasisCollection;
@JoinTable(name = "advertisement_to_child_care_type_join", joinColumns = {
@JoinColumn(name = "advertisement_ID", referencedColumnName = "advertisement_ID", nullable = false)}, inverseJoinColumns = {
@JoinColumn(name = "child_care_type_ID", referencedColumnName = "child_care_type_ID", nullable = false)})
@ManyToMany
private Collection<ChildCareType> childCareTypeCollection;
@JoinTable(name = "advertisement_to_school_holiday_join", joinColumns = {
@JoinColumn(name = "advertisement_ID", referencedColumnName = "advertisement_ID", nullable = false)}, inverseJoinColumns = {
@JoinColumn(name = "school_holiday_ID", referencedColumnName = "school_holiday_ID", nullable = false)})
@ManyToMany
private Collection<SchoolHoliday> schoolHolidayCollection;
@JoinTable(name = "employment_contract_to_advertisement_join", joinColumns = {
@JoinColumn(name = "advertisement_ID", referencedColumnName = "advertisement_ID", nullable = false)}, inverseJoinColumns = {
@JoinColumn(name = "employment_contract_ID", referencedColumnName = "employment_contract_ID", nullable = false)})
@ManyToMany
private Collection<EmploymentContract> employmentContractCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "advertisement")
private Collection<AdvertisementToTimeSlotToDayJoin> advertisementToTimeSlotToDayJoinCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "advertisementID")
private Collection<Salary> salaryCollection;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "advertisement")
private ParentToParentAdvertisement parentToParentAdvertisement;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "advertisement")
private ParentToChildMinderAdvertisement parentToChildMinderAdvertisement;
@JoinColumn(name = "child_care_location_ID", referencedColumnName = "child_care_location_ID", nullable = false)
@ManyToOne(optional = false)
private ChildCareLocation childcarelocationID;
@JoinColumn(name = "account_ID", referencedColumnName = "account_ID", nullable = false)
@ManyToOne(optional = false)
private Account accountID;



@Entity
@Table(name = "advertisement_to_time_slot_to_day_join",schema="bignibou")
@NamedQueries({
@NamedQuery(name = "AdvertisementToTimeSlotToDayJoin.findAll", query = "SELECT a FROM AdvertisementToTimeSlotToDayJoin a"),
@NamedQuery(name = "AdvertisementToTimeSlotToDayJoin.findByDayID", query = "SELECT a FROM AdvertisementToTimeSlotToDayJoin a WHERE a.advertisementToTimeSlotToDayJoinPK.dayID = :dayID"),
@NamedQuery(name = "AdvertisementToTimeSlotToDayJoin.findByTimeslotID", query = "SELECT a FROM AdvertisementToTimeSlotToDayJoin a WHERE a.advertisementToTimeSlotToDayJoinPK.timeslotID = :timeslotID"),
@NamedQuery(name = "AdvertisementToTimeSlotToDayJoin.findByAdvertisementID", query = "SELECT a FROM AdvertisementToTimeSlotToDayJoin a WHERE a.advertisementToTimeSlotToDayJoinPK.advertisementID = :advertisementID")})
public class AdvertisementToTimeSlotToDayJoin implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected AdvertisementToTimeSlotToDayJoinPK advertisementToTimeSlotToDayJoinPK;
@JoinColumn(name = "time_slot_ID", referencedColumnName = "time_slot_ID", nullable = false, insertable = false, updatable = false)
@ManyToOne(optional = false)
private TimeSlot timeSlot;
@JoinColumn(name = "day_ID", referencedColumnName = "day_ID", nullable = false, insertable = false, updatable = false)
@ManyToOne(optional = false)
private Day day;
@JoinColumn(name = "advertisement_ID", referencedColumnName = "advertisement_ID", nullable = false, insertable = false, updatable = false)
@ManyToOne(optional = false)
private Advertisement advertisement;

最佳答案

这里的基本想法是您必须分两个阶段保存实体。当然,您可以在同一笔交易中完成。首先,保存订单,而不保存 LineItem,然后检索订单的 PK,然后将其设置在 LineItem 上,然后保存 LineItem。我猜想是 OneToMany 注释的 CascadeType 属性会告诉 JPA 在两个不同的阶段执行此操作,即在保存订单时不保存 LineItems。像这样的事情:

@Entity
public class Order {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
long id;

@OneToMany(cascade={})
Set<LineItem> lineItems;
}

或者您可以在保存订单时将 lineItems 设置为空,然后检索 PK,设置 lineItems 以及 lineItems 的 PK,然后再次保存订单。

如果您的数据库设计是最终的且无法更改,请忽略答案的这一部分。

这是我的个人意见(基于多年的数据库设计和维护)。因此,首先,您是否有充分的理由在 LineItem 中使用复合 PK,而不是使用良好的旧 surrogate primary key

因为如果不这样做,那么您应该在 LineItem 中有一个代理主键。否则,您将不断遇到各种问题(例如,如果您碰巧必须迁移数据)

编辑我的建议:

  1. 在数据库中:在表中使用 auto_increment PK,如下例所示:http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
  2. 在 JPA 映射中:选择本文中的第一个选项 (AUTO):http://www.objectdb.com/java/jpa/entity/generated

关于mysql - Mysql 自动生成的 PK 用于另一个表和 JPA 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8897300/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com