Question

Using Spring 3.2.0, Eclipselink 2.5.0-M9

When persistence.xml contains:

<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

Then if I examine the EntityManagerFactory during runtime, via emf.getProperties(), this property is not set.

However, if I put it in my Spring entityManagerFactory configuration instead:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  ...
  <property name="jpaPropertyMap">
    <map>
      <entry key="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE" />
    </map>
  </property>
</bean>

Then I can retrieve the property from emf.getProperties()

Also, it appears that when using the spring config, the shared cache is not actually enabled. this leads me to believe that I'm not setting it correctly in the spring container.

Ideas?

Was it helpful?

Solution

<shared-cache-mode>

Is not a persistence unit property, but an element in the persistence.xml. I'm not sure what setting "javax.persistence.sharedCache.mode" as a property does, but my guess is it is just set as a persistence unit property, and ignored.

But default, EclipseLink enables the shared cache, so you do not need to configure it.

If you are not seeing caching being used, it could be because of the Spring bug, https://jira.springsource.org/browse/SPR-7753, in which case there is a workaround using setLazyDatabaseTransaction() option in the EclipseLinkJpaDialect.

ENABLE_SELECTIVE I think mean only enable caching for Entities that have @Cacheable(true), so that may not be what you want.

OTHER TIPS

I found this workaround to enable shared cache in EclipseLink in Spring environment:

@Bean
public EntityManagerFactory entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setDataSource(dataSource());
    factory.setPersistenceUnitName("main");

    final EclipseLinkJpaDialect customDialect = new EclipseLinkJpaDialect() {
        @Override
        public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException {
            // Hides: return super.getJdbcConnection(entityManager, readOnly);
            // IMPORTANT LINE
            return null;
        }
    };

    // IMPORTANT LINE
    customDialect.setLazyDatabaseTransaction(true);

    EclipseLinkJpaVendorAdapter customAdapter = new EclipseLinkJpaVendorAdapter() {
        @Override
        public JpaDialect getJpaDialect() {
            return customDialect;
        }
    };

    customAdapter.setDatabase(Database.ORACLE);
    factory.setJpaVendorAdapter(customAdapter);

    factory.afterPropertiesSet();
    return factory.getObject();
}

I found this article very useful.
The conclusion is writing,

JPA caching is flexible enough to configure per class basis or globally with the help of persistence unit settings or class settings. We can either set shared-cache-mode element in the persistence.xml or dynamically set javax.persistence.sharedCache.mode property while creating entity manager factory. In concurrent transactions, setting the cache mode to NONE in view of better performance may on the contrary lead to performance slowdown and is not recommended; such situations should rather be handled with an appropriate locking mechanism.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top