【问题标题】:Share common query result for all Hibernate Entities共享所有 Hibernate 实体的通用查询结果
【发布时间】:2017-07-27 18:23:15
【问题描述】:

我目前正在使用具有 Hibernate 实现的 JPA 实体,我想知道是否有办法在同一类的所有实体之间共享某个查询结果?

我想要的是在实体中实现一个简单的 Transient 方法,它检查当前实体的某些属性是否在存储在数据库中另一个表中的值列表中,但我不希望每个实体都执行这个额外查询以获取值列表。

有没有办法存储这个缓存的查询结果并在特定实体中访问它?

例如:

个人实体:

private Long id;
private String name;

...

@Transient
public boolean isIdBanned(){
(check against the cached list)
} 

在这里,我想使用缓存的查询结果检查 Person 的 id 是否在禁止的 ids 列表中。

【问题讨论】:

  • 是否可以安全地假设此缓存列表是您的应用程序在应用程序全局静态注册表中保存的东西,或者它是否可能是 Web 拦截器加载一次并且您为此重用缓存列表的东西特殊要求?
  • @Naros 现在列表存储在配置数据库表中。

标签: java hibernate jpa caching entity


【解决方案1】:

这是我通常提倡分离 domainpersistence 对象的地方。

从持久性的角度来看,您的Person 实体并不关心这个禁止列表。从持久性的角度来看,它绝对没有具体的用途,因此我认为它不属于Person 实体的任何地方。

从您的域的角度来看,您基本上是在尝试满足为您的域提供一种询问Person 的方式的要求,“嘿,你被禁止了吗?”

@Service
public class PersonBanService {
  @Cacheable
  @Transactional(readOnly = true)
  public List<Integer> getBanList() {
    return personBanRepository.findAll();
  }
}

@Service
public class PersonDomainService {
  @Transactional(readOnly = true)
  public List<Person> getPersons() {
    List<Integer> banList = personBanService.getBanList();
    List<PersonEntity> people = personRepository.findAll();
    return people.stream()
      .map( p -> new Person( p, banList.contains( p.getId() ) ) )
      .collect( Collectors.toList() );
  }
}

基本上,PersonDomainService 充当这两个问题的中介。它会在每个域方法调用中为您获取一次禁止列表,然后将其与 PersonEntity 实例一起传递给内部使用该列表的域包装类 Person

这里的好处是PersonBanService 可以选择缓存返回的结果,允许在集群或多个请求调用之间共享该列表,而无需使用任何可用的缓存框架访问数据库。

现在在您的 Person 域对象中

public Person(PersonEntity entity, boolean banned) { 
  this.person = entity;
  this.banned = banned;
}

public boolean isBanned() {
  return banned;
}

【讨论】:

  • 谢谢!我以前没有考虑过这种方法!
猜你喜欢
  • 1970-01-01
  • 2017-07-08
  • 2021-04-21
  • 2019-12-24
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 2013-08-15
  • 2013-10-20
相关资源
最近更新 更多