Gregor
Gregor

Reputation: 3027

MongoTemplate in MultiTenant Spring Data Mongo Application

This is a follow up to the question Making spring-data-mongodb multi-tenant Oliver Gierke explained options how to set-up multi-tenancy for a SpringDataMongo application. I followed his "collection approach" and was quite successful. So far. Problems arise, when I want to customise the MongoTemplate used. Have a look on this example:

@SpringBootApplication
public class MultiTenantMongoApplication {

    public static void main(String[] args) {
        SpringApplication.run(MultiTenantMongoApplication.class, args);
    }

    @Bean
    public MongoTemplate mongoTemplate(Mongo mongo, @Value("${random.name}") String randomName) throws Exception {
        String dbname = "db_" + randomName;
        MongoTemplate mongoTemplate = new MongoTemplate(mongo, dbname) {
            @SuppressWarnings("unused")
            public void shutdown() {
                mongo.dropDatabase(dbname);
            }
        };
        return mongoTemplate;
    }
}

@Document(collection="#{tenantProvider.getTenantCollectionName('Metric')}")
public class Metric {

}

@Repository
public interface MetricRepository extends MongoRepository<Metric, ObjectId>{}

@Component
public class TenantProvider {
    public String getTenantCollectionName(String collectionName) {
        ...
    }
}

This yields the following error:

SpelEvaluationException: EL1007E: Property or field 'tenantProvider' cannot be found on null

When I remove the definition of the MongoTemplate bean in the application class everything is fine and runs as desired. Obviously the property provider gets not configured appropriately, when the MongoTemplate is customised. Why is this happening? And what can I do, to get the property in place?

Upvotes: 1

Views: 585

Answers (1)

Sunand Padmanabhan
Sunand Padmanabhan

Reputation: 656

I think the above error is because of the SpEL expression. You can try this way to access the TenantProvider class using the below SpEL expression.

#{T(TenantProvider).getTenantCollectionName('Metric')}

or you can add a fully qualified class name for TenantProvider in the above expression.

Upvotes: 0

Related Questions