我在优化Hibernate查询时遇到问题,以避免执行连接或二次选择 .
执行Hibernate查询(条件或hql)时,如下所示:
return getSession().createQuery(("from GiftCard as card where card.recipientNotificationRequested=1").list();
...和where子句检查不需要与其他表连接的属性...但是Hibernate仍然与其他表执行完全连接(或者根据我设置fetchMode的方式进行二次选择) .
有问题的对象(GiftCard)有一些ManyToOne关联,在这种情况下我宁愿懒洋洋地加载(但不一定是所有情况) . 我想要一个解决方案,我可以控制在执行查询时延迟加载的内容 .
这就是GiftCard实体的样子:
@Entity
@Table(name = "giftCards")
public class GiftCard implements Serializable
{
private static final long serialVersionUID = 1L;
private String id_;
private User buyer_;
private boolean isRecipientNotificationRequested_;
@Id
public String getId()
{
return this.id_;
}
public void setId(String id)
{
this.id_ = id;
}
@ManyToOne
@JoinColumn(name = "buyerUserId")
@NotFound(action = NotFoundAction.IGNORE)
public User getBuyer()
{
return this.buyer_;
}
public void setBuyer(User buyer)
{
this.buyer_ = buyer;
}
@Column(name="isRecipientNotificationRequested", nullable=false, columnDefinition="tinyint")
public boolean isRecipientNotificationRequested()
{
return this.isRecipientNotificationRequested_;
}
public void setRecipientNotificationRequested(boolean isRecipientNotificationRequested)
{
this.isRecipientNotificationRequested_ = isRecipientNotificationRequested;
}
}
2 回答
如上所述
如果您有这样的映射
任何* ToOne关系,例如@OneToOne和@ManyToOne,默认情况下都是FetchType.EAGER,这意味着它将始终被提取 . 但是,它可能不是你想要的 . 你说什么,我可以控制什么是懒惰加载可以翻译为 Fetching Strategy . POJO in Action book支持这样的模式(通知方法签名)
因此,根据您的用例,您可以创建自己的查找...使用...和...方法 . 它会照顾 just what you want
但它有一个问题:它不支持通用方法签名 . 对于每个@Entity存储库,您必须定义自定义查找...使用...和方法 . 因此,我向您展示了如何定义通用存储库
但是, sometimes ,您不希望通用Repository接口定义的所有方法 . 解决方案:创建一个将实现虚拟存储库的AbstractRepository类 . 例如,Spring Framework, heavily use this kind of pattern Interface >> AbstractInterface
所以你的GiftCardRepository可以重写为(参见extends而不是implements)和 just overrides what you really want
现在,我们将我们的命名查询外部化为多行 - 可读且可维护的 - xml文件
因此,如果您想通过买家取回GiftCard,请致电
要在没有任何关系的情况下检索我们的GiftCard,只需致电
或使用import static
和
我希望它对你有用!
在JPA中,
ManyToOne
关联的默认提取类型是急切的(即非惰性),因此您可以尝试:然后,在任何JPA查询中,可以使用
left join fetch
急切地获取关联 .