Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate 2nd level cache one-to-one doesn't work

I use Ehcache provider for Hibernate 2nd level cache. It caches one-to-many collections, annotated with @Cache, but does not cache one-to-one:

//hb annotations
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "user")
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region = "details")
    private Details details;

    //getters, setters, constructors etc.

}

//hb annotations
public class Details {

    @GenericGenerator(name = "generator", strategy = "foreign",
    parameters = @Parameter(name = "property", value = "user"))
    @Id
    @GeneratedValue(generator = "generator")
    @Column(unique = true, nullable = false)
    private Integer id;

    @OneToOne
    @PrimaryKeyJoinColumn
    private User user;

    //getters, setters, constructors ets.

}

I use Spring JpaRepository to fetch the data:

userRepository.findOne(id);
like image 902
Feeco Avatar asked Oct 14 '16 01:10

Feeco


1 Answers

For ToOne associations only the id (foreign key) of the associated entity instance is cached in the entry of the owning instance:

Hibernate stores cached entities in a dehydrated form, which is similar to the database representation. Aside from the foreign key column values of the @ManyToOne or @OneToOne child-side associations, entity relationships are not stored in the cache.

So, the associated entity has to be loaded by its id when the owning instance is assembled from the L2 cache. To avoid that, make the associated entity (Details in your case) cachable as well.

More details available also here and here.

like image 89
Dragan Bozanovic Avatar answered Oct 11 '22 11:10

Dragan Bozanovic