Spring Data JPARepository:如何有条件地获取子实体
除非提供了某个执行参数,否则如何将其JPA实体配置为不获取相关实体。
根据Spring的文档4.3.9。配置Fetch-和LoadGraphs时,您需要使用@EntityGraph
批注为查询指定获取策略,但是,这不能让我在运行时决定是否要加载这些实体。
我可以在一个单独的查询中获得子实体,但为此,我需要将自己的存储库或实体配置为不检索任何子实体。不幸的是,我似乎找不到任何有关执行此操作的策略。FetchPolicy
将被忽略,并且EntityGraph
仅在指定我要热切检索的实体时才有用。
例如,假设假定Account
是父项,Contact
是子项,并且一个帐户可以有多个联系人。
if(fetchPolicy.contains("contacts")){ account.setContacts(contactRepository.findByAccountId(account.getAccountId());
}
问题是无论如何弹簧数据都急切地获取联系人。
@Entity@Table(name = "accounts")
public class Account
{
protected String accountId;
protected Collection<Contact> contacts;
@OneToMany
//@OneToMany(fetch=FetchType.LAZY) --> doesn't work, Spring Repositories ignore this
@JoinColumn(name="account_id", referencedColumnName="account_id")
public Collection<Contact> getContacts()
{
return contacts;
}
//getters & setters
}
public interface AccountRepository extends JpaRepository<Account, String>{
//@EntityGraph ... <-- has type= LOAD or FETCH, but neither can help me prevent retrieval
Account findOne(String id);
}
回答:
如果没有调用由getContacts()导致的对象方法,则延迟获取应该正常工作。
如果您希望进行更多的人工工作,并且确实希望对此进行控制(根据使用情况,可能需要更多上下文)。我建议您从帐户实体中删除联系人,并将该帐户映射到联系人中。告诉hibernate状态忽略该字段的一种方法是使用@Transient批注对其进行映射。
@Entity@Table(name = "accounts")
public class Account
{
protected String accountId;
protected Collection<Contact> contacts;
@Transient
public Collection<Contact> getContacts()
{
return contacts;
}
//getters & setters
}
然后在服务类中,您可以执行以下操作:
public Account getAccountById(int accountId, Set<String> fetchPolicy) { Account account = accountRepository.findOne(accountId);
if(fetchPolicy.contains("contacts")){
account.setContacts(contactRepository.findByAccountId(account.getAccountId());
}
return account;
}
希望这是您想要的。顺便说一句,该代码未经测试,因此您可能应该再次检查。
以上是 Spring Data JPARepository:如何有条件地获取子实体 的全部内容, 来源链接: utcz.com/qa/417122.html