- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我假设我遇到了 N+1 选择问题。
我得到了这个实体:
@Entity
@Table(name = "Devices")
public class Device implements Serializable {
@OneToOne(mappedBy="holdingDevice", fetch=FetchType.LAZY)
@Cascade(CascadeType.ALL)
@PrimaryKeyJoinColumn
private WarrantyEntry warranty;
}
这是另一个实体:
@Entity
@Table(name = "Warranty")
public class WarrantyEntry implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@OneToOne
@JoinColumn(name = "serial")
@PrimaryKeyJoinColumn
private Device holdingDevice;
现在当我开始迭代这个循环时:
Set<Device> customerDevices = user.getCustomer().getDevices();
for (Device device : customerDevices) {
...
}
我被卡住了,我在日志中看到 Hibernate 选择:
hibernate :*/选择warrantyen0_.id作为...Hibernate:/* 加载 myclass.Device */
hibernate :*/选择 Warrantyen0_.id 作为 ..Hibernate:/* 加载 myclass.Device */...
我一次又一次地猜想我遇到了 n+1 选择问题。
有什么建议我如何解决并用一个选项替换所有这些选择?
完成此操作后
String query="from Customer c left join fetch c.devices d \n" +
"left join fetch d.tradeInOldDevice " +
"left join fetch d.tradeInNewDevice "+
"left join fetch d.warranty";
deviceDao.getSessionFactory().openSession().createQuery(query);
for (Device device : customerDevices) {
..
}
我仍然明白:
Hibernate:
devices0_.owningCompany_customerRefId as owningC15_0_1_,
devices0_.serial as serial1_,
devices0_.serial as serial9_0_,
devices0_.blackListed as blackLis2_9_0_,
devices0_.Creation_id as Creation12_9_0_,
devices0_.deactivated as deactiva3_9_0_,
devices0_.deviceComment as deviceCo4_9_0_,
devices0_.deviceName as deviceName9_0_,
devices0_.deviceType as deviceType9_0_,
devices0_.distributor_customerRefId as distrib13_9_0_,
devices0_.endCustomer_customerRefId as endCust14_9_0_,
devices0_.owningCompany_customerRefId as owningC15_9_0_,
devices0_.paChallenge as paChalle7_9_0_,
devices0_.parent_serial as parent16_9_0_,
devices0_.pendingDeactivation as pendingD8_9_0_,
devices0_.safetyStock as safetySt9_9_0_,
devices0_.serialSalt as serialSalt9_0_,
devices0_.signedBlackBerry as signedB11_9_0_,
devices0_.tradeInOldDevice as tradeIn17_9_0_
from
Devices devices0_
where
devices0_.owningCompany_customerRefId=?
Hibernate:
device0_.serial as serial9_0_,
device0_.blackListed as blackLis2_9_0_,
device0_.Creation_id as Creation12_9_0_,
device0_.deactivated as deactiva3_9_0_,
device0_.deviceComment as deviceCo4_9_0_,
device0_.deviceName as deviceName9_0_,
device0_.deviceType as deviceType9_0_,
device0_.distributor_customerRefId as distrib13_9_0_,
device0_.endCustomer_customerRefId as endCust14_9_0_,
device0_.owningCompany_customerRefId as owningC15_9_0_,
device0_.paChallenge as paChalle7_9_0_,
device0_.parent_serial as parent16_9_0_,
device0_.pendingDeactivation as pendingD8_9_0_,
device0_.safetyStock as safetySt9_9_0_,
device0_.serialSalt as serialSalt9_0_,
device0_.signedBlackBerry as signedB11_9_0_,
device0_.tradeInOldDevice as tradeIn17_9_0_
from
Devices device0_
where
device0_.tradeInOldDevice=?
Hibernate:
warrantyen0_.id as id34_2_,
warrantyen0_.createdTime as createdT2_34_2_,
warrantyen0_.deleted as deleted34_2_,
warrantyen0_.expiryDate as expiryDate34_2_,
warrantyen0_.serial as serial34_2_,
warrantyen0_.updateTime as updateTime34_2_,
warrantyen0_.updateUser as updateUser34_2_,
device1_.serial as serial9_0_,
device1_.blackListed as blackLis2_9_0_,
device1_.Creation_id as Creation12_9_0_,
device1_.deactivated as deactiva3_9_0_,
device1_.deviceComment as deviceCo4_9_0_,
device1_.deviceName as deviceName9_0_,
device1_.deviceType as deviceType9_0_,
device1_.distributor_customerRefId as distrib13_9_0_,
device1_.endCustomer_customerRefId as endCust14_9_0_,
device1_.owningCompany_customerRefId as owningC15_9_0_,
device1_.paChallenge as paChalle7_9_0_,
device1_.parent_serial as parent16_9_0_,
device1_.pendingDeactivation as pendingD8_9_0_,
device1_.safetyStock as safetySt9_9_0_,
device1_.serialSalt as serialSalt9_0_,
device1_.signedBlackBerry as signedB11_9_0_,
device1_.tradeInOldDevice as tradeIn17_9_0_,
management2_.id as id22_1_,
management2_1_.deleted as deleted22_1_,
management2_1_.firstName as firstName22_1_,
management2_1_.lastLogin as lastLogin22_1_,
management2_1_.lastName as lastName22_1_,
management2_1_.password as password22_1_,
management2_1_.primaryEmail as primaryE7_22_1_,
management2_1_.userName as userName22_1_,
management2_.authority as authority23_1_,
management2_.isViewer as isViewer23_1_,
management2_3_.distributor as distribu1_25_1_,
management2_4_.umeKeysQuota as umeKeysQ1_27_1_,
case
when management2_2_.id is not null then 2
when management2_3_.id is not null then 3
when management2_4_.id is not null then 5
when management2_5_.id is not null then 6
when management2_6_.id is not null then 7
when management2_.id is not null then 1
end as clazz_1_,
cids3_.Users_id as Users1_22_4_,
cids3_.element as element4_,
emails4_.Users_id as Users1_22_5_,
emails4_.element as element5_,
roles5_.Users_Management_id as Users1_22_6_,
roles5_.element as element6_
from
Warranty warrantyen0_
left outer join
Devices device1_
on warrantyen0_.serial=device1_.serial
left outer join
Users_Management management2_
on warrantyen0_.updateUser=management2_.id
left outer join
Users management2_1_
on management2_.id=management2_1_.id
left outer join
Users_Management_Administrators management2_2_
on management2_.id=management2_2_.id
left outer join
Users_Management_Distributors management2_3_
on management2_.id=management2_3_.id
left outer join
Users_Management_Limited management2_4_
on management2_.id=management2_4_.id
left outer join
Users_Management_Managers management2_5_
on management2_.id=management2_5_.id
left outer join
Users_Management_Workers management2_6_
on management2_.id=management2_6_.id
left outer join
Users_CID cids3_
on management2_.id=cids3_.Users_id
left outer join
Users_Emails emails4_
on management2_.id=emails4_.Users_id
left outer join
Users_Management_roles roles5_
on management2_.id=roles5_.Users_Management_id
where
warrantyen0_.serial=?
谢谢,射线。
最佳答案
假设您已在 Customer
类中定义了 customerDevices
关联,如下所示:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "device")
private Set<Device> customerDevices;
这种LAZY
映射关联会让您面临n+1
选择问题。让我们考虑一个简单的查询,该查询检索给定 customerId
的 customer
:
session().createQuery("from Customer c where c.name=:name").setParameter("name", name);
这将返回一个 customer
,其中 customerDevices
的集合是未初始化的集合包装器。现在,当您迭代循环时:
Set<Device> customerDevices = user.getCustomer().getDevices();
for (Device device : customerDevices) {
...
}
在访问设备
集合时,Hibernate 必须从数据库中获取这个惰性集合,执行额外的select
语句。
针对此问题的推荐解决方案是在代码中覆盖运行时的默认获取策略,您可以通过使用如下查询来实现:
session().createQuery(from Customer c left join fetch c.devices d
left join fetch d.warrantyEntry)
这将返回一个 Customer
以及关联的集合。因此,不要只检索初始查询中的顶级对象,而是通过准确指定哪些数据来获取初始查询中所有需要的数据。将在正在进行的工作单元中访问关联。
编辑:
看起来有时一对一映射会导致 HQL 急切获取失败。您可以在这些讨论中找到有关此问题的更多信息:HQL eager fetch failure和 N+1 selects on left join .
其中提到的一个解决方案是将 OneToOne
映射更改为 ManyToOne
和 OneToMany
,我尝试过(使用类似类型的模型类) )并且它非常适合我。我通过一个 sql 查询获得了选择的所有结果。
例如,在 Device
类中,您可以将 OneToOne
映射更改为 ManyToOne
:
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "warrantyFK", unique = true)
private WarrantyEntry warranty;
unique=true
属性将使此关联成为一对一关联,因为没有两个 Device
可以具有相同的 WarrantyEntry
。您可以在 WarrantyEntry
类中定义 Device
的集合:
@OneToMany(mappedBy = "warranty")
private Set<Device> holdingDevices;
主要思想是使用 OneToMany
和 ManyToOne
而不是 OneToOne
。您只需确保最多向映射 OneToMany
一侧的 set
添加一项。
关于java - Hibernate 因 OneToOne 的多项选择而陷入困境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18848711/
我正在使用 OneWayToSource绑定(bind),它似乎总是将我的源属性设置为空。为什么呢?这给我带来了麻烦,因为我需要源属性中目标属性的值而不是空值。 这是我的代码: MyViewModel
我有一个实例变量属性,它被声明和实例化,如下所示: $self->{properties}{$key1} = $value; 我的理解是这将声明属性字段,并将其设置为包含一个键值对的哈希原语。 我正
我正在尝试检查给定的数字是否是质数。首先采用试分割法。但该程序的行为很奇怪。这是我使用的。 int no; no = Integer.parseInt(jTextField1.getText());
我正在使用 NSUserDefaults使一个对象在多个 UIViewController 之间保持同步UITabbarController 中使用的 s .为此,我正在实现以下 - (void)vi
考虑以下 Java 方法: public Boolean compare(String val1, String val2) { return val1.length() > 0 && val
我有一个问题...假设我有一个包含城市名称的表。像这样: id name 1 Los Angeles 2 Madrid 我有一张用户表: uid username locationid
我无法理解这个问题。该代码非常基本,但它的行为却出乎意料。该代码是例程的简化版本,用于从每日数据库中提取每月第 15 天的数据并将其保存到单独的文件中。哪里有问题 ?第一个 cout 打印输入外部 i
我在 中使用大背景标签,我想制作一个宽度为 960px 的容器 div。我希望容器 div 位于从顶部向下 15px 的位置,我想我必须使用 position:absolute。我的困境是;容器内的
我遇到了一个难题。我有一个 hashedX 字段,它是一个散列值/加盐值,按照惯例,加盐值保存在 mysql 数据库的同一行中。 hashedX saltX ------ ---
类 java.io.Reader 和 java.io.InputStreamReader 都有具有完全相同签名的读取方法 public int read(char[] charbuf, int off
我有一个包含多个 C# 项目的 C# 解决方案。我打算在其中添加日志记录。此日志记录应该在所有项目中可用,并且最好使用带有滚动文件日志的 log4Net。 在上述前提下,我可以想到两种方法。 在解决方
我开始学习Python,目前我非常喜欢它。但是,如果你能帮我回答几个问题,这些问题一直困扰着我,我找不到任何明确的答案: 就语言兼容性而言,Python 的 C 实现(来自 python.org 的主
我正在尝试使用 AVAssetWriter 将 CGImages 写入文件以从图像创建视频。 我已经让它在模拟器上以三种不同的方式成功运行,但在运行 iOS 4.3 的 iPhone 4 上,每种方法
我需要对一个想法进行建模,可以将其分解并考虑如下: 图书详细信息 图书价格 这里的问题是您可以为书籍设置许多价格,并且这些价格可能会发生变化。这是一个例子 图书详细信息: --------------
我有一个表,其中的行包含名为 MySubId 的列。此列中的值可以重复。我想找到 MySubId 值和出现次数最多的 MySubId 值的行数。 我有以下查询: SELECT MySubId, COU
我有两个具有多对多关系的类,因此我在它们之间创建了一个联接表(一个非常经典的示例!) 在java+hibernate中我想知道哪种方式更好?使用hibernate多对多注释在这两个类之间有多对多关系吗
我正在尝试创建一个 Android 应用程序来完成以下任务:它通过短信向一组收件人(存储在数组中的数字)发送初始调查问题。然后,对于收到的每个响应,它都会向该参与者发送该系列中的下一个问题。这是我做过
这里有一个关于 IncludeEventHandler 的有趣问题。 我正在开发一个基于 Spring 的应用程序,该应用程序使用具有单独投资组合站点的不同供应商的速度。我让供应商通过向他们提供存储在
我真的无法理解事件和委托(delegate)的概念。我知道委托(delegate)是持有方法引用的对象,可以调用具有相同返回类型和参数的方法,但事件到底是什么? 如果我需要使用事件来制作一个简单的计算
在我正在处理的一个项目中,我有一个扩展 JFrame 的主类(名为 TrackWin)。在此框架中,我使用 JTabbedPane。 用户可以从菜单栏在 Pane 中创建新选项卡。每当发生这种情况时,
我是一名优秀的程序员,十分优秀!