[英]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年
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.