使用自然ID的Hibernate实体缓存

时间:2018-09-22 11:26:04

标签: java hibernate caching ehcache naturalid

我有一个实体Note,该实体由Dictionary中的字段“ code”连接。我想获取所有笔记,但是有n + 1问题。当我获取笔记时,休眠状态也会从表Dicionary中获取数据,每个笔记一个额外的查询(如果字典不在一级缓存中)。

我启用了二级缓存(我正在使用ehcache),仅当我通过ID获取字典时才起作用,也许有一种方法可以使用自然ID?我不想使用查询缓存。也许我应该将词典从二级缓存加载到一级缓存?

@Entity
public class Note {

    @Id
    private Long id;

    @ManyToOne
    @JoinColumn(referencedColumnName = "code")
    private Dictionary noteType;
}


@Entity
@NaturalIdCache
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Dictionary {

    @Id
    private Long id;

    @NaturalId
    @Column(unique = true, nullable = false, updatable = false, insertable = false)
    private String code;
}


@org.springframework.stereotype.Repository
public interface NoteRepository extends Repository<Note, Long> {
    List<Note> findAll();
}


@RestController
@RequiredArgsConstructor
class NoteController {

    private final NoteRepository noteRepository;

    @GetMapping("\all")
    public List<Note> getAll() {
        return noteRepository.findAll();
    }
}

我希望这足够清楚。谢谢。

1 个答案:

答案 0 :(得分:0)

根据13.2. Configuring second-level cache mappings,您必须在@javax.persistence.Cacheable上使用Dictionary

  

除非明确标记为可缓存(带有   @Cacheable注释)。

根据13.4. Entity cache

  

Hibernate二级缓存还可以通过其实体加载实体   自然ID

this.em.unwrap(Session.class)
    .bySimpleNaturalId(AppConfig.class)
    .load(appConfigEnum.getValue());