每个类层次结构继承使用一张表时的 hibernate 获取策略
你好 我正在使用每个类层次结构一个表继承映射到旧数据,如此处所述
是我的映射大致的样子
<class abstract="true" name="note" table="NOTES">
<id name="id" type="long" column="NOTE_ID">
<generator class="native"/>
</id>
<discriminator column="NOTE_TYPE" type="string"/>
<property name="orderId" column="ORDER_ID"/>
<property name="text" column="TEXT"/>
<subclass name="PurchaseNote" discriminator-value="PUR" />
<subclass name="CancelNote" discriminator-value="CAN" />
<subclass name="RefundNote" discriminator-value="REF" />
</class>
这 每个订单 id 可以是注释的许多子类。
注释被描述为订单类中的关联,就像
<class name="order" table="ORDERS">
<id name="id" type="long" column="ORDER_ID">
<generator class="native"/>
</id>
.....
<set name="purchaseNotes">
<key column="orderId" />
<one-to-many class="PurchaseNote"/>
</set>
<set name="cancelNotes">
<key column="orderId" />
<one-to-many class="cancelNote"/>
</set>
<set name="refundNotes">
<key column="orderId" />
<one-to-many class="refundNote"/>
</set>
</class>
如果我执行以下操作,我可以获取由 hibernate 获取的关联集合。
1) 在订单 xml 的集合定义中使用“Where”子句 或者 2)使用force =“true”作为注释xml中鉴别器定义的一部分
我还可以在通过会话工厂的hibernate会话进行DAO调用时,使用HQL “来自 RefundNote,其中 orderId = ?” 或者 “来自 Note note,其中 note.class = RefundNote 且 orderId = ?”获取正确的 RefundNote 子类的列表,并使用 returnedNotes 上的 setter 填充 Order 类中的列表。
所有标准的休眠内容?
这些方法中的任何一种都会创建对同一个表发出 3 个查询(每个集合一个)的集合。随着子类数量的增加,这似乎效率低下......?
我读过很多书,但看不出休眠(通过获取策略、加入、子选择等)可以最大限度地减少对单个数据库调用的调用并仍然填充我的集合的任何方式......?
我可以获取所有注释并在 Java 中迭代以通过 class.simpleName 检查构建集合,但想知道我是否缺少 hibernate 会做的事情......?
感谢您的任何建议
Hello
I am using the one table per class hierarchy inheritance mapping to legacy data as described here
here is what my mapping roughly looks like
<class abstract="true" name="note" table="NOTES">
<id name="id" type="long" column="NOTE_ID">
<generator class="native"/>
</id>
<discriminator column="NOTE_TYPE" type="string"/>
<property name="orderId" column="ORDER_ID"/>
<property name="text" column="TEXT"/>
<subclass name="PurchaseNote" discriminator-value="PUR" />
<subclass name="CancelNote" discriminator-value="CAN" />
<subclass name="RefundNote" discriminator-value="REF" />
</class>
There can be many subclasses of notes to each order id
The Notes are described as associations in a Order Class something like
<class name="order" table="ORDERS">
<id name="id" type="long" column="ORDER_ID">
<generator class="native"/>
</id>
.....
<set name="purchaseNotes">
<key column="orderId" />
<one-to-many class="PurchaseNote"/>
</set>
<set name="cancelNotes">
<key column="orderId" />
<one-to-many class="cancelNote"/>
</set>
<set name="refundNotes">
<key column="orderId" />
<one-to-many class="refundNote"/>
</set>
</class>
I can get the associated collections fetched by hibernate if I do the following.
1) Use a "Where" clause in the set definition in the order xml
or
2) Use a force="true" as part of the discriminator definition in the notes xml
I can also, in a DAO call through a hibernate session from a session factory, use the HQL
"from RefundNote where orderId = ?"
or
"from Note note where note.class = RefundNote and orderId = ?" to get a list of the correct RefundNote subclasses and populate the list in the Order class by using the setter on refundNotes.
All standard hibernate stuff?
Any of these methods will create the collections firing off 3 queries (one for each collection) to the same table. As the number of subclasses grows this seems ineffiecient....?
I've read lots but can't see any way that hibernate (through fetch strategies, join,subselect,etc) could minimise these calls to a singe db call and still populate my collections.....?
I can get all notes and iterate through in Java to build the collections through class.simpleName inspection but was wondering if I'm missing something hibernate will do.....?
Thanks for any advice
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我必须深入研究代码来验证,但我怀疑这就是 Hibernate 处理这样的映射关联的方式 - 它总是会对每个水合关联进行一次数据库调用。
另一种方法是拥有一个映射的 Hibernate 集合、Notes,然后拥有退款注释等瞬态字段。
在特定类型的 getter 中,迭代 Notes 集合以查找感兴趣的特定注释。在您的设置器中,将其添加到常规注释集合中。
这样,hibernate 将进行单个查询来获取笔记,并且您可以根据需要对水合对象进行操作。
I'd have to dig deep into the code to verify, but I suspect this is simply how Hibernate handles mapped associations like this - it's always going to make one database call per hydrated association.
An alternative approach is to have one mapped hibernate collection, Notes, and then have transient fields for refundNotes, etc.
In the getter for your specific types, iterate over the notes collection to find the specific notes of interest. In your setter, have it add to the general notes collection.
This way, hibernate will make the single query to fetch the notes, and you can operate on the hydrated objects as needed.