繁体   English   中英

如何通过JPA保留数据而无需主键

[英]How to persist data through JPA without needing a primary key

我有流经我的应用程序的数据,通常不需要打扰,但是要实现一项新功能,我需要将其临时存储(例如1个小时)。 输入的数据可以与其中已经存在的数据完全相同,因此不需要主键。 但是,使用JPA实体需要一个ID,但我不需要/想要一个。 这使我无法正常工作。

这是通过Spring使用JPA实现的。 由于数据经常移入和移出数据库,因此不建议使用自动生成的ID,因为它会在几年后通过ID。 我试图使其可嵌入,它说我需要进行组件扫描以找到它的使用位置,但是如果我将其设置为实体,则它会提示我它需要主键。

这是我的实体,用于存储我需要保留的数据。

@Entity
@Table(name = "quoteOrderHistory")
public class QuoteOrderHistory {

    @Column(name = "storeNumber")
    private int storeNumber;

    @Column(name = "invoiceNumber")
    private String invoiceNumber;

    @Column(name = "quoteSaleDate")
    private Date quoteSaleDate;

    @Column(name="orderTotal")
    private BigDecimal orderTotal;

    @Column(name="orderHistoryDate")
    private Timestamp orderHistoryDate;

    // Constructors, Getters and Setters

}

这是我访问数据的存储库。

@Repository
public interface QuoteOrderHistoryRepository extends JpaRepository<QuoteOrderHistory, Long> {

    @Query("DELETE FROM QuoteOrderHistory q WHERE q.orderHistoryDate > date")
    void deleteAllExpired(Date date);

    @Query("SELECT q FROM QuoteOrderHistory q WHERE q.storeNumber = ?1 AND q.invoiceNumber = ?2 ORDER BY q.orderHistoryDate DESC")
    List<QuoteOrderHistory> findAllByStoreAndInvoiceDesc(int storeNumber, String invoiceNumber);
}

我不知道该怎么做。 同样,不需要主键,因为它假定支持重复项。 如果没有使用JPA的另一种解决方法,那么我全力以赴,但是目前看来,持久保存数据是最容易的。 如果您需要更多信息,请告诉我。 我也可能缺少可以避免这些事情的方法,但是我对JPA并不熟悉。 因此,感谢所有帮助。

如果使用正确的大小,则不应使ID用完一列。 停止尝试与您的框架作斗争,只添加一个自动递增的列。

https://hashrocket.com/blog/posts/running-out-of-ids

假设业务非常好,我们每分钟将10,000条记录插入表中。 那么,最大化序列所需的时间是多少? 1750380517年

ID可以进入Postgresql多大

Name        Storage Size    Description                       Range
smallint    2 bytes         small-range integer               -32768 to +32767
integer     4 bytes         usual choice for integer          -2147483648 to +2147483647
bigint      8 bytes         large-range integer               -9223372036854775808 to 9223372036854775807
serial      4 bytes         autoincrementing integer          1 to 2147483647
bigserial   8 bytes         large autoincrementing integer    1 to 9223372036854775807

如果由于某种我无法理解的原因而急于不使用id列,则看起来您可以在JPA中通过将每个列作为主键描述的一部分来进行操作,但是您的删除和更新操作将删除/更新任何记录数。 我没有尝试过。 我不会在生产服务器上实现此功能。

https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#No_Primary_Key

有时您的对象或表没有主键。 在这种情况下,最好的解决方案通常是将生成的ID添加到对象和表。 如果没有此选项,则有时表中有一列或一组列组成唯一值。 您可以将此唯一的列集用作JPA中的ID。 JPA Id不必总是与数据库表的主键约束匹配,也不需要主键或唯一约束。

如果您的表确实没有唯一列,则将所有列用作ID。 通常,发生这种情况时,数据是只读的,因此,即使表允许具有相同值的重复行,对象也将始终相同,因此JPA认为它们是同一对象无关紧要。 允许更新和删除的问题在于,无法唯一标识对象的行,因此所有匹配的行都将被更新或删除。

如果您的对象没有ID,但是其表具有ID,则可以。 将对象设为可嵌入对象,可嵌入对象没有ID。 您将需要一个包含此Embeddable的实体来持久化并查询它。

Jazzepi说的是正确的,但严格要求我不要使用自动生成的数字作为ID。 因此,人们在此处使用UUID对此进行了链接。 这是解决此问题的最佳选择,因为数据库中的对象被安排在其中的时间不超过几个小时。 既然是这种情况,那么UUID将永远不会溢出,并且在任何给定时间在表内重复UUID的可能性几乎为零,因为大多数情况下不会保留在那里。

新实体类:

@Entity
@Table(name = "quoteOrderHistory")
public class QuoteOrderHistory {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
    @Column(name = "uuid", unique = true)
    private String uuid;

    @Column(name = "storeNumber")
    private int storeNumber;

    @Column(name = "invoiceNumber")
    private String invoiceNumber;

    @Column(name = "quoteSaleDate")
    private Date quoteSaleDate;

    @Column(name="orderTotal")
    private BigDecimal orderTotal;

    @Column(name="orderHistoryDate")
    private Timestamp orderHistoryDate;

    // Constructor, getters, setters

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM