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

回到顶部