spring-bootgemfirespring-data-gemfire

Spring Data Gemfire: TTL expiration annotation is not working; how to set TTL using annotations?


In Gfsh, I was able to do: create region --name=employee --type=REPLICATE --enable-statistics=true --entry-time-to-live-expiration=900.

We have a requirement to create a Region using Java using the @EnableEntityDefinedRegions annotation. When I use describe in Gfsh the Regions are showing, but entity time to live expiration (TTL) is not setting by using below ways.

Any idea how to set TTL in Java?

Spring Boot 2.5.x and spring-gemfire-starter 1.2.13.RELEASE are used in the app.

@EnableStatistics
@EnableExpiration(policies = {
        @EnableExpiration.ExpirationPolicy(regionNames = "Employee", timeout = 60, action = ExpirationActionType.DESTROY))
})
@EnableEntityDefinedRegions 
public class BaseApplication {
....

@Region("Employee")
public class Employee {

or

@EnableStatistics
@EnableExpiration
public class BaseApplication {
----

@Region("Employee")
@TimeToLiveExpiration(timeout = "60", action = "DESTROY")
@Expiration(timeout = "60", action = "DESTROY")
public class Employee {
....

or

using bean creation way also not working, getting error "operation is not supported on a client cache"

@EnableEntityDefinedRegions
//@PeerCacheApplication  for peer cache Region is not creating PCC gemfire 
public class BaseApplication {
---
}
   
@Bean(name="employee")
PartitionedRegionFactoryBean<String, Employee> getEmployee
        (final GemFireCache cache,
         RegionAttributes<String, Employee> peopleRegionAttributes) {
    PartitionedRegionFactoryBean<String, Employee> getEmployee = new PartitionedRegionFactoryBean<String, Employee>();
    getEmployee.setCache(cache);
    getEmployee.setAttributes(peopleRegionAttributes);
    getEmployee.setCache(cache);
    getEmployee.setClose(false);
    getEmployee.setName("Employee");
    getEmployee.setPersistent(false);
    getEmployee.setDataPolicy( DataPolicy.PARTITION);
    getEmployee.setStatisticsEnabled( true );
    getEmployee.setEntryTimeToLive( new ExpirationAttributes(60) );
    return getEmployee;
}

@Bean
@SuppressWarnings("unchecked")
RegionAttributesFactoryBean EmployeeAttributes() {
    RegionAttributesFactoryBean EmployeeAttributes = new RegionAttributesFactoryBean();

    EmployeeAttributes.setKeyConstraint( String.class );
    EmployeeAttributes.setValueConstraint( Employee.class );

 }

Solution

  • First, Spring Boot for Apache Geode (SBDG) 1.2.x is already EOL because Spring Boot 2.2.x is EOL (see details on support). SBDG follows Spring Boot's support lifecycle and policies.

    Second, SBDG 1.2.x is based on Spring Boot 2.2.x. See the Version Compatibility Matrix for further details. We will not support mismatched dependency versions. While mismatched dependency versions may work in certain cases (mileage varies depending on your use case), the version combinations not explicitly stated in the Version Compatibility Matrix will not be supported none-the-less. Also see the documentation on this matter.

    Now, regarding your problem with TTL Region entry expiration policies...

    SBDG auto-configuration creates an Apache Geode ClientCache instance by default (see docs). You cannot create a PARTITION Region using a ClientCache instance.

    If your Spring Boot application is intended to be a peer Cache instance in an Apache Geode cluster (server-side), then you must explicitly declare your intention by overriding SBDG's auto-configuration, like so:

    @PeerCacheApplication
    @SpringBootApplication
    class MySpringBootApacheGeodePeerCacheApplication { 
        // ...
    }
    

    TIP: See the documentation on creating peer Cache applications using SBDG.

    Keep in mind that when you override SBDG's auto-configuration, then you may necessarily and implicitly be responsible for other aspects of Apache Geode's configuration, e.g. Security! Heed the warning.

    On the other hand, if your intent is to truly enable your Spring Boot/SBDG application as a cache "client" (i.e. a ClientCache instance, the default), then TTL Region entry expiration policies do not make sense on client PROXY Regions, which is the default DataPolicy (EMPTY) for client Regions when using the Spring Data for Apache Geode (SDG) @EnableEntityDefinedRegions annotation (see Javadoc). This is because Apache Geode client PROXY Regions do not store any data locally. All data access operations are forward to the server/cluster.

    Even if you alter the configuration to use client CACHING_PROXY Regions, the TTL Region expiration policies will only take effect locally. You must configure your corresponding server/cluster Regions, separately (e.g. using Gfsh).

    Also, even though you can push cluster configuration from the client using SDG's @EnableClusterConfiguration (doc, Javadoc), or alternatively and preferably, SBDG's @EnableClusterAware annotation (doc, Javadoc; which is meta-annotated with SDG's @EnableClusterConfiguation), this functionality only pushes Region and Index configuration to the cluster, not expiration policies.

    See the SBDG documentation on expiration for further details. This doc also leads to SDG's documentation on expiration, and specifically Annotation-based expiration configuration.

    I see that the SBDG docs are not real clear on the matter of expiration, so I have filed an Issue ticket in SBDG to make this more clear.