我有流经我的应用程序的数据,通常不需要打扰,但要实现一项新功能,我需要临时存储它(例如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并不熟悉。因此,感谢所有帮助。
答案 0 :(得分:2)
如果使用正确的大小,则列的ID不会用完。停止尝试使用您的框架,只需添加一个自动递增的列即可。
https://hashrocket.com/blog/posts/running-out-of-ids
比方说,生意如此好,我们每个月插入10,000条记录 分钟到我们的桌子。因此,要花多长时间才能最大限度地利用我们 顺序? 1750380517年
来自How large can an id get in 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。您将需要一个包含此可嵌入对象的实体才能持久 并查询它。
答案 1 :(得分:0)
Jazzepi说的是正确的,但严格要求我不要使用自动生成的数字作为ID。因此,人们使用UUID链接了此here描绘。这是解决此问题的最佳选择,因为数据库中的对象被安排在其中的时间不超过几个小时。既然是这种情况,那么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
}