我想按如下方式为产品实现定价:
- Product 对象包含一个描述其当前价格的 Pricing 对象。
- Product 表以一对多关系链接到 Pricing 表
+------------+ +---------------------+ | Product | | Price | +------------+ 1-n +---------------------+ | product_id | ----------- | product_id | | ... | | price_id | +------------+ | price_value | | price_creation_time | | ... | +---------------------+
Sounds simple enough so far, but the part I'm having trouble with is
- The Product has only one active Price, namely the most recent one.
- Any pricing records prior to the most recent one shouldn't be fetched.
- When the user edits a product's pricing, the current record should not be updated, a new one with a current timestamp should be inserted instead.
- The previous pricing records are kept for historical reasons (such as seeing what a customer wanting a refund paid for the product at the time of purchase).
Essentially, from within the Product object, the relationship should appear as if it was a one-to-one relationship. However, I don't know how to implement such a thing using Hibernate
Last Record of one to many relation Hibernate Criteria suggests something called Criteria may be of help, but I have very little Hibernate experience and am still getting to grips with the class annotation.
Is it possible to implement a one-to-many relationship such that is appears to be a one-to-one relationship like this with Hibernate? How would I go about doing it?
UPDATE: A bit more info on the idea is as follows:
A receipt will consist of a collection of records for each item bought.
+--------------+ +------------------+ | Receipt | | ReceiptLine | +---------+ +--------------+ +------------------+ +----- | Product | | receipt_id | ----------- | receipt_id | | +---------+ | receipt_time | | product_id | -----+ +-------+ | ... | | price_id | ----------- | Price | +--------------+ | product_quantity | +-------+ | ... | +------------------+
Products have a current price (and obviously only one current price) which is determined by the price record in the price table that has the most recent timestampe.
SELECT *
FROM prices
WHERE product_id = (Product ID goes here)
ORDER BY price_creation_time;
LIMIT 1;
当您更新定价时,我想插入一条新的定价记录,而不是更新当前链接到产品的定价记录。
INSERT INTO price (
product_id,
price_value,
price_creation_time
) VALUES (
(Product ID goes here),
(New price goes here),
NOW()
);
当顾客购买东西时,每购买一件元素,收据记录中都会添加一行。每行都包含产品的 ID,cut 还包括生成收据时适用的定价记录的 ID。这样我就可以知道客户在购买产品时支付了多少费用。
此数据还可用于尚未定义的会计和其他数据挖掘 Activity 。
最佳答案
- The Product has only one active Price, namely the most recent one.
- Any pricing records prior to the most recent one shouldn't be fetched.
您可以使用 Hibernate filters 来实现此目的.这将允许您在不初始化整个集合的情况下检索集合的某些元素。在这种情况下,您只想获取一个 Price
来自 price collection
的元素(最近的一个)出现在你的Product
类(class)。
将此过滤器定义添加到您的 Product
映射文件(首先使用 <filter-def/>
元素中的 <hibernate-mapping/>
元素定义过滤器,然后将过滤器附加到 price
集合):
<hibernate-mapping package="x.y.z">
<class name="Product" table="product_table_name">
....
<set name="priceList" inverse="true" cascade="save-update" lazy="true">
...
<filter name="priceFilter"
condition="price_id = (select max(p.price_id) from Price p where
p.product_id = product_id)" />
</set>
</class>
<filter-def name="priceFilter"/>
</hibernate-mapping>
此过滤器将加载 price
max(price_id) 是最近为 product
添加的价格.现在您需要为给定 session 启用此过滤器,可以按如下方式完成:
session.enableFilter("priceFilter");
为了确保向您提供 Product
与最近相关Price
,在检索产品数据之前在 session 中启用过滤器:
session.enableFilter("priceFilter");
Criteria criteria = session.createCriteria(Product.class);
criteria.setFetchMode("priceList", FetchMode.JOIN);
criteria.add(Restrictions.eq("id", productId));
Product product = (Product) criteria.uniqueResult();
使用此过滤器,关系将显示为一对一关系。关联的价目表将仅包含一个 Price
(最近的一个)。如果您不使用 session.enableFilter("stateFilter")
启用过滤器, Hibernate 将加载所有关联的价格。
- When the user edits a product's pricing, the current record should not be updated, a new one with a current timestamp should be inserted instead.
- The previous pricing records are kept for historical reasons (such as seeing what a customer wanting a refund paid for the product at the time of purchase).
假设您有一个 set
的 prices
与特定 product
相关联,这可以通过以下方式方便地完成 updatePrice
Product
中的方法类:
private Set<Price> priceList = new HashSet<Price>();
...
public void updatePrice(Price price) {
price.setId(null);// Hibernate will execute an INSERT statement
price.setProduct(this);
priceList.add(price);
}
想法是设置Id
Price
的属性(property)至 null
在添加更新的 price
之前到 priceList
的 product
.
如果您向价目表添加一个新价格,这个新价格将根据“按可达性持久化”变得持久化。当原始实例变为持久实例时或就在内存中状态与数据存储同步之前,从持久实例可访问的所有对象都变为持久实例。
关于java - 选择最近的相关记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18681905/