Search code examples
javahibernatejpaormsecond-level-cache

Mapping two CacheConcurrencyStrategy for the same Hibernate second-level cache region


I have set different cache strategies like 'read-write' and 'read-only' usage for a single region, when i try to update Carro Entity, the following exception was thrown:

ERROR org.hibernate.internal.SessionImpl - HHH000346: Error during managed flush [Can't write to a readonly object]

Exception in thread "main" java.lang.UnsupportedOperationException: Can't write to a readonly object

If I separate entities in different regions work. So, can't have two different types strategies on the same region?

Ps.: Receive this warn too: HHH020007: read-only cache configured for mutable entity


-> Carro:

@Entity
@Table(name = "carro")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region = "myregion")
public class Carro implements Serializable
{ 
     private static final long serialVersionUID = 8467432396096896736L;

     @Id
     @Column(name = "id")
     private Integer id;

     @Column(name = "carro")
     private String carro;

     @OneToMany(mappedBy = "carro", fetch = FetchType.LAZY)
     private List<Pessoa> pessoas = new ArrayList<Pessoa>();
}

-> Pessoa:

@Entity
@Table(name = "pessoa")
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "myregion")
public class Pessoa implements Serializable
{
    private static final long serialVersionUID = 8467432396096896736L;

    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "nome")
    private String Nome;

    @Column(name = "sexo")
    private String sexo;

    @Column(name = "idade")
    private Integer idade;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "carro_id")
    private Carro carro;
}

-> ehcache.xml:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
         monitoring="autodetect" dynamicConfig="true">

    <cache name="myregion" maxEntriesLocalHeap="1000" eternal="false" timeToLiveSeconds="1000">
        <persistence strategy="none"/>
    </cache>

    <cache name="org.hibernate.cache.internal.StandardQueryCache" maxEntriesLocalHeap="1000" eternal="false" timeToLiveSeconds="120">
        <persistence strategy="none"/>
    </cache>

    <cache name="org.hibernate.cache.spi.UpdateTimestampsCache" maxEntriesLocalHeap="1000" eternal="true">
        <persistence strategy="none"/>
    </cache>
</ehcache>

Solution

  • The region must have a single CacheConcurrencyStrategy. In your case, the Pessoa class must have been registered after Carro, so myregion is set to READ_ONLY.

    By default, each entity has a different region factory, so you can set a different CacheConcurrencyStrategy on a per entity basis.