2

I have an entity Note which is joined by field 'code' in Dictionary. I would like to fetch all notes but there is n+1 problem . When I'm fetching notes hibernate also fetching data from table Dicionary , one additional query per one note (if the dictionary is no already in first level cache).

I enabled 2nd level cache (I am using ehcache) which work only when I am fetching Dictionaries by ID , maybe there is a way how to use natural id ? I do not want to use query cache. Maybe I should load Dictionaries from second level cache to first level cache ?

@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();
    }
}

I hope this is clear enough. Thank you.

Grzesiek
  • 41
  • 3

1 Answers1

0

According to 13.2. Configuring second-level cache mappings you have to use @javax.persistence.Cacheable on Dictionary:

Entities are not cached unless explicitly marked as cacheable (with the @Cacheable annotation).

According to 13.4. Entity cache:

The Hibernate second-level cache can also load entities by their natural id

this.em.unwrap(Session.class)
    .bySimpleNaturalId(AppConfig.class)
    .load(appConfigEnum.getValue());
Adrian
  • 3,321
  • 2
  • 29
  • 46