Why the Mongodb queries become slowly - java

I setup a Java web application project which is based on MongoDB. The DAO of the this project is implemented by MongoDB Java driver; I didn't use the Spring Data for MongoDB.
I'm getting a performance problem. If the application sends a query to the database, the response time is about 17ms. But if I used the Jmeter -- which mocked about 300 users -- the response time of 90%Line is about 1300ms. The response time is intolerable. I tried to find the reason, but I don't know.
Also, there is the MongoUri String:
mongo.uri=mongodb://192.168.1.172:27017,192.168.1.172:22222,192.168.1.172:33333/?replicaSet=yyyy&maxPoolSize=100&ssl=false&readPreference=secondaryPreferred&connectTimeoutMS=10000&socketTimeoutMS=10000&safe=false&
The query is just like a query for an objectID, like db.collection.find( { _id: xxxx } ). Also, I've constructed the index on _id.
mongo.xml
<bean id="uri" class="com.mongodb.MongoClientURI">
<constructor-arg value="${mongo.uri}"></constructor-arg>
</bean>
<bean id="mongoClient" class="com.mongodb.MongoClient">
<constructor-arg ref="uri"></constructor-arg>
</bean>
<bean id="mongoCollectionDao" class="com.xxx.api.domain.dao.impl.MongoCollectionDao" lazy-init="false">
<constructor-arg name="mongoClient" ref="mongoClient"></constructor-arg>
<constructor-arg name="mongoDatabaseName" value="${mongo.database}"></constructor-arg>
</bean>
Could anyone explain what's going wrong here?

Related

How to Change Property Value at Runtime without restart application server in Spring MVC

We have Spring scheduled job with cron expression which is configured in database. I need to change schedule time without restart the application server. But i could not achieve this and i have tried many ways using SO solutions in other link, but none worked for me. Below is my code snippet.
Scheduler time will get from database during dispatcher servlet initializing and assign in the property variable test.scheduler
Scheduler.java
#Scheduled(cron = "${test.scheduler}")
public void testScheduler() {
System.out.println("Dynamic Scheduler Run Test"+new java.util.Date().getTime());
}
dispatcher-servlet.xml
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="properties">
<bean class="org.apache.commons.configuration.ConfigurationConverter" factory-method="getProperties">
<constructor-arg>
<bean class="org.apache.commons.configuration.DatabaseConfiguration">
<constructor-arg>
<ref bean="dataSource" />
</constructor-arg>
<constructor-arg value="TABLE_NAME" />
<constructor-arg value="TABLE_KEY" />
<constructor-arg value="TABLE_VALUE" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
From the table (TABLE_NAME), there is column's key is test.scheduler & value is 0 0/5 * * * ?
As far as I am aware, SpEL won't let you change the value of your scheduler once it has been initialised.
If you are using Spring Boot, you will be able to use Actuator to trigger a refreshed event:-
http://localhost:8080/actuator/refresh
In which case, you can make the bean implement RefreshedScope and update your scheduler by triggering the RefreshScopeRefreshedEvent:
#EventListener(RefreshScopeRefreshedEvent.class)
public void onRefresh(RefreshScopeRefreshedEvent event) {
// Read the database, update the scheduler.
}
An example implementation of this can be seen here.
This might not be the perfect solution to your problems but I am posting it for visibility and to help others.
An alternative solution may involve using a Trigger to determine the next execution time. An example StackOverflow answer can be seen here.

Configure Apache Commons Pool to create objects on start up

I'm configuring a pool of objects using apache commons pool2. It seems the objects in the pool are only created when an attempt is made to borrow an object. I'd like the objects to be created up front, so I have a minimum number of objects ready when the first one needs to be borrowed.
My spring configuration looks something like this:
<bean id="webSocketConnectionPool" class="org.apache.commons.pool2.impl.GenericObjectPool">
<constructor-arg ref="webSocketConnectionFactory"/>
<constructor-arg ref="webSocketConnectionPoolConfig"/>
</bean>
<bean id="webSocketConnectionFactory" class="com.blah.WebSocketConnectionFactory" />
<bean id="webSocketConnectionPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
<property name="maxIdle" value="300"/>
<property name="maxTotal" value="1000"/>
<property name="minIdle" value="10"/>
</bean>
I can see the pool is created when the app starts, but the minIdle setting doesn't seem to result in my desired behaviour. The create() method on the factory is only called when the first object is borrowed.
Any tips would be appreciated.
Thanks
My solution was to add some logic to the init method of the class with the connection pool as a member, to add objects. Hopefully this will help someone else in the future.
connectionPool.addObjects(connectionPool.getMinIdle());

Spring batch dynamic file writer

Does spring batch provide any dynamic/generic file writers? For example, if i have multiple requirements of generating a file and i have one view created for each purpose, all i want to do is specify the view name and i want spring-batch to extract the data from the view to a flat file with column headings. This is as simple as if you have used dbviz or sql developer, just export the result of a query to a file.
Recently i had 4 different requirements of extracting data to file, and i have repeated the config file and created a record bean and record mapper to map the bean to the columns of view for each file. Rather than repeating this entire process every time, i am looking to see if Spring batch or any other java frameworks provides a generic approach to extracting a file based on the table and its columns without writing result set mappers or dealing with field extractors.
I can build a generic spring batch file extractor but wanted to check if spring-batch already does that, which seems like a basic thing?
Also if i create a generic extractor then the attributes of the bean will be kinda dynamic based on the columns names of the view. So in that scenario, if i have about 50 columns i dont want to specify each attribute in fieldExtractor, i want all the attributes to be extracted. Currently i am specifying attributes in spring config as given below, but i don't want to spefiy the attribute names. I just want to say extract all attributes. Is that possible?
<bean id="CsvItemWriter" class="some.class.FileWriter" scope="step">
<property name="resource" value="file://#{jobParameters['file.name']}"/>
<property name="shouldDeleteIfExists" value="true" />
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter">
<util:constant static-field="org.springframework.batch.item.file.transform.DelimitedLineTokenizer.DELIMITER_TAB" />
</property>
<property name="fieldExtractor"> <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="name.last, name.first, name.middle, birthDate, gender, homePhone, cellPhone"/>
</bean>
</property>
</bean>
</property>
In case some one needs it, i found a similar question in SO that was difficult to find. I am using columnMapRowMapper as mentioned here

Adt message converters - INTEGERS come as nulls

I am using following configuration for handling OracleAQ with adt payload...
<bean id="messageConverter"
class="org.springframework.data.jdbc.jms.support.converter.oracle.MappingAdtMessageConverter">
<constructor-arg>
<bean class="org.springframework.data.jdbc.jms.support.oracle.StructDatumMapper">
<constructor-arg index="0" value="MY_QUEUE"/>
<constructor-arg index="1" value="MyMappedClass"/>
</bean>
</constructor-arg>
</bean>
the problem is that after dequeuing I am getting on java side null values for fields with INTEGERs and non null values for other fields.
MyMappedClass#649fe46f[
id=<null>
id2=<null>
time=2013-02-22 14:57:11.0
user=LUKAS
]
In queue table these values exists as not nulls.
What can be the reason. I expected bad mappings, but I don't see anything wrong there.
Those fields are mapped as Types.INTEGER.
Do you have maybe idea what can be the reason?
Finally I've found that there are mistakes in generated mapping files. For Long field I had Integer setter. That was the reason why reflection api during conversion process regarded those fields as non writeable. So it was not library version or configuration problem.

Sending data from client to server in Spring

I am developing a web application using spring MVC, Hiberbate and MySQL database. I am trying to send data to server from a client, but I can not do it.
In detail,
I want to send my JSON data to http://localhost:8080/app/test . In my test controller I want to get the data which comes from the client and write it to screen or save it to db. I have been searching about 3 days and I have tried many strategies to do it, but I can not.
You must explicitly tell spring to use a json parser.
For instance, here is a piece of my DispatcherServlet config :
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
Jackson Must be in your classpath.
Then you write a method like this one in your annotated controller :
#RequestMapping(value = "/test", method = RequestMethod.POST)
public void myMethod(#RequestBody MyObject object) {
//... do what you want with the object
}
You just have to send an JSON object with properties that match the ones in MyObject, via a POST request.

Categories