CraigR8806 CraigR8806 - 1 month ago 21
Java Question

Spring utilizing Mongo implementation over JPA

I am fairly new to the Spring Framework and have been having some trouble setting up the project I am currently working on. I need to be able to connect to two different databases one being MongoDB and the other being MSSQL. I am using JPA to connect to the MSSQL.

The problem that I am encountering is that it appears to be trying to make calls to the Mongo database when I want it to make calls to the MSSQL and I'm not really sure how to tell it what to read from. I have seen the posts advising to use the

@Qualifier
annotation to direct it to the correct implementation, but I don't think that that will work for my case.

@RestController
@RequestMapping("/software")
public class SoftwareEndpoint {



@Autowired
SoftwareRepository repo;


/**********************************************************************************
********************************MSSQL calls****************************************
***********************************************************************************/
@RequestMapping(value="/all",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON)
String getAllSoftware(){

System.out.println("Here1");
List<Software> allSoftware = (List<Software>) repo.findAll();
System.out.println("Here2");
//rest of method and class


Above shows a snippet of my controller class that has an instance of my SoftwareRepository. I also print to the out stream before and after the db call.

The out stream only shows "Here1", goes on to print out this line:

2016-10-04 07:35:39.810 INFO 4236 --- [nio-8080-exec-2] org.mongodb.driver.cluster : No server chosen by ReadPreferenceServerSelector{readPreference=primary} from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, all=[ServerDescription{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused: connect}}]}. Waiting for 30000 ms before timing out


and then throws an exception on timeout.

I do not have a mongo instance running locally, however there will be on where the application is being deployed, but I don't believe that this is the problem because on hitting that endpoint, it shouldn't be making a call to the Mongo database, it should be trying to reach out to MSSQL.

TLDR: How do I specify which database implementation for Spring to use for a specific repository or database call?

Answer

You can connect to different databases in spring based on the configuration in context.

The below code is for connecting to MySql and Mongo DB. You can substitute MySql with MSSQL provided you have the JDBC for it. Check http://jdbforms.sourceforge.net/UsersGuide/html/ch20s02.html for what the properties for JDBC connection mean.

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg ref="mySqldataSource" /> <!-- Change the datasource to MSSQL-->
    </bean>

    <bean id="mySqldataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="removeAbandoned">
            <value>true</value>
        </property>
        <property name="removeAbandonedTimeout">
            <value>30</value>
        </property>
        <property name="driverClassName">
            <value>MSSQL_DRIVER_CLASS_NAME</value>
        </property>
        <property name="url">
            <value>MSSQL_DATABASE_URL</value>
        </property>
        <property name="username">
            <value>MSSQL_DB_USER_NAME</value>
        </property>
        <property name="password">
            <value>MSSQL_DB_PASSWORD</value>
        </property>
        <property name="maxIdle"> 
            <value>10</value>
        </property>
        <property name="maxActive"> 
            <value>10</value>
        </property>
        <property name="maxWait">
            <value>100000</value>
        </property>
        <property name="testOnBorrow">
            <value>false</value>
        </property>
        <property name="testWhileIdle">
            <value>false</value>
        </property>
        <property name="timeBetweenEvictionRunsMillis">
            <value>60000</value>
        </property>
        <property name="minEvictableIdleTimeMillis">
            <value>60000</value>
        </property>
        <property name="numTestsPerEvictionRun">
            <value>1</value>
        </property>
        <property name="defaultTransactionIsolation" value="1" />
        <property name="poolPreparedStatements" value="true" />
        <property name="maxOpenPreparedStatements" value="1" />
    </bean>

    <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"></bean>

Below is for connecting to mongodb

    <mongo:db-factory dbname="mongoDbName" host="mongoServer" port="mongoPort"/>


    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean>
    <mongo:repositories base-package="com.test.repoPackage"/> <!-- Package containing the mongo repository interfaces -->

Now you can use the repositories provided by spring.

EDIT 1: Suppose name of config is springConfig.properties. In the above example for the properties dbname, host and port in mongo:db-factory, you would want the values to be configured in springConfig.properties. So lets name them below:

mongoServer = xxx.xx.xxx.xxx
mongoPort = 27017
mongoDb = testDb

Now the context file needs to be modified to import the springConfig.properties. this is done as below in the context file:

<bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
        <property name="locations" >
            <list>              
                <value>classpath:/log4j.properties</value>
                <value>classpath:/springConfig.properties</value>
            </list>
        </property>
    </bean>

The bean mongo:db-factory would now look like:

<mongo:db-factory dbname="${mongoDb}" host="${mongoServer}" port="${mongoPort}"/>

Notice that the "keys" from config (dbname, host and port) are represented insde ${}. This will replace with values in config for the keys.

Comments