共享所有Hibernate实体的公共查询结果

时间:2017-03-07 13:50:26

标签: java hibernate jpa caching entity

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

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

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

例如:

人物实体:

private Long id;
private String name;

...

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

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

1 个答案:

答案 0 :(得分:1)

我通常会主张将持久性对象分开。

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

从您的域名来看,您基本上都在努力满足为您的域名提供Person" He您被禁止的方式的要求?"

@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可以选择缓存返回的结果,允许该列表在集群或多个请求调用中共享,而无需使用您可用的任何缓存框架来访问数据库。 / p>

现在位于Person域对象

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

public boolean isBanned() {
  return banned;
}