1

我有一个名为 PetOwner 的实体。PetOwner 有一个宠物列表。每个宠物都有一个商店(即:这个宠物来自的商店)。Pet 是一个抽象类,获得一个具体版本会执行很多连接 ( @Inheritance(strategy = InheritanceType.JOINED))。我想在 PetOwner 上有一个带有这个签名的方法:

Set<Store> getAllStores();

问题是加载宠物列表非常慢,实际上没有必要获取商店列表。当我打电话时getAllStores,我希望它像这样运行 SQL:

SELECT DISTINCT store_id
FROM pet
WHERE petowner_id = x;

但如果我这样实现它:

Set<Stores> stores = //
for (pet : pets)
   stores.add(pet.getStore());
return stores;

它会拉入所有宠物并且非常缓慢。那么我怎样才能防止它拉进所有的宠物呢?理想情况下,我确实希望在 PetOwner 对象上使用此方法,因为我认为这样的代码更加面向对象。

此外,在 PetOwner 中还有其他方法,即使速度很慢,我也确实需要加载宠物列表。但我并不总是调用它,这就是为什么我只想要这种方法来避免加载宠物列表。

4

2 回答 2

1

我假设您有一项服务可以用来获取您的 PetOwners。我建议您在服务上创建一个新方法,而不是将您的方法添加到 PetOwner。

public Set<Stores> getStoresForOwner( PetOwner owner );

并使用您用于数据访问层的任何内容(hibernate 模板、Spring-data-jpa 存储库、EntityManager 直接)使用命名查询进行调用。

@NamedQuery(name="PetOwnerStore.findAll", query="SELECT distinct p.Store from Pet p where p.Owner.id = :petOwnerId");

可以说,由于您是从 Pet 中选择的,因此 JPA 可能无论如何都必须完成所有连接......

以上所有假设(除其他外,因为您没有提供任何实体映射) Pet 和 Store 之间的关系是惰性获取,因此尚未填充。

于 2013-02-07T23:34:08.980 回答
1

没有标准的方法可以做到这一点,因为您没有映射此数据。我看到的不同选项是

  1. 直接在 EM 上使用命名查询
  2. 将方法添加到 PetOwner 接受 ENntityManager 并直接进行查询,或者
  3. 向宠物主人添加一个临时列表,并将其填充到运行查询的加载后事件中。除非重新加载 PetOwner,否则这将无法看到更新。
于 2013-02-08T12:29:16.107 回答