poseidon_rishi
poseidon_rishi

Reputation: 81

Spring DATA for RDBMS and NoSql

Is it possible to make an application using Spring DATA with common code that supports both RDMS and Nosql(MongoDb) as back-end data store.It should support either one of them at one point of time and it should be configurable.

Upvotes: 0

Views: 1040

Answers (2)

gjrwebber
gjrwebber

Reputation: 2658

I have just pushed a new Spring-Data project named spring-data-gremlin which aims to do exactly this. It uses JPA annotations to map to any Tinkerpop blueprints graph database (OrientDB, TitanDB, etc). This means that switching between RDBMS and nosql graph databases should be a matter of configuration for any Spring-Data-JPA project.

Note: The project is in early stages of development and therefore not all JPA annotations are implemented yet.

Upvotes: 1

rikica
rikica

Reputation: 351

I don't know for sure for MongoDB but we currently have projects configured with Spring Data JPA and Spring Data Neo4J simultaneously. I can't think of any obstacles why you could not make this work with Spring Data JPA and Spring Data MongoDB.

Be aware of transaction management: as far as I know MongoDB does not support transactionability so any kind of writing to both data sources can not be done as atom operation. If this is not an issue, you're good to go.

Our example snippet:

<neo4j:config storeDirectory="${neo4j.storeDirectory}"
        base-package="app.model.neo4j" />
<neo4j:repositories base-package="app.neo4j.repo" />
<tx:annotation-driven transaction-manager="neo4jTransactionManager" />

And Spring Data JPA in Configuration annotated class:

@Configuration
@EnableJpaRepositories(value = "app.dao", entityManagerFactoryRef = "emf", transactionManagerRef = "tm")
@ComponentScan("app")
@EnableTransactionManagement
public class ConfigDao {

        protected final String  PROPERTY_DB_MODEL_PACKAGESTOSCAN    = "db.model.packagesToScan";
        protected final String  PROPERTY_DB_DRIVER_CLASSNAME        = "db.driver.className";
        protected final String  PROPERTY_DB_URL                     = "db.url";
        protected final String  PROPERTY_DB_USERNAME                = "db.username";
        protected final String  PROPERTY_DB_PASSWORD                = "db.password";
        protected final String  PROPERTY_DB_ADDITIONAL_DDL          = "hibernate.hbm2ddl.auto";
        protected final String  PROPERTY_DB_ADDITIONAL_DIALECT      = "hibernate.dialect";
        protected final String  PROPERTY_DB_ADDITIONAL_EMF_NAME     = "hibernate.ejb.entitymanager_factory_name";

        @Bean
        public DataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName(PROPERTY_DB_DRIVER_CLASSNAME);
            dataSource.setUrl(PROPERTY_DB_URL);
            dataSource.setUsername(PROPERTY_DB_USERNAME);
            dataSource.setPassword(PROPERTY_DB_PASSWORD);
            return dataSource;
        }

        @Bean
        public PlatformTransactionManager transactionManager() {
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
            return transactionManager;
        }

        @Bean
        public EntityManager entityManager() {
            return entityManagerFactory().getObject().createEntityManager();
        }

        @Bean
        public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
            LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
            em.setDataSource(dataSource());
            em.setPackagesToScan(PROPERTY_DB_MODEL_PACKAGESTOSCAN);
            JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            em.setJpaVendorAdapter(vendorAdapter);
            em.setJpaProperties(additionalJpaProperties());
            return em;
        }

        @Bean
        protected Properties additionalJpaProperties() {
            Properties properties = new Properties();
            properties.setProperty(PROPERTY_DB_ADDITIONAL_DDL);
            properties.setProperty(PROPERTY_DB_ADDITIONAL_DIALECT);
            properties.setProperty(PROPERTY_DB_ADDITIONAL_EMF_NAME);
            return properties;
        }

}

Hope it helps.

Upvotes: 0

Related Questions