I'm using google maps to plot markers on a map. I can save the data for ALL these points (it's over 17000 rows with 3 columns: shopId,shopName,lat,long).
I can also send JSON queries specifying my lat/long and the radius at what shops around I want data about. Then I'll receive the data back. This works, but when I create the markers (with AsyncTask) freezing occurs in the app (and it is noticeable).
This is the code I'm using to generate the custom markers on Google maps:
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
JSONArray jsonArray = new JSONArray(result);
String finalReturn[] = result.split("\\r?\\n");
if(jsonArray.get(0).toString().equals("4")) {
for (int i = 1; i < finalReturn.length; i++) {
jsonArray = new JSONArray(finalReturn[i]);
IconGenerator iconGenerator = new IconGenerator(getApplicationContext());
iconGenerator.setStyle(IconGenerator.STYLE_RED);
iconGenerator.setRotation(90);
iconGenerator.setContentRotation(-90);
Bitmap iconBitmap = iconGenerator.makeIcon(jsonArray.get(5).toString());
Marker marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(jsonArray.getDouble(6), jsonArray.getDouble(7)))
.icon(BitmapDescriptorFactory.fromBitmap(iconBitmap)));
marker.setTitle(jsonArray.getString(1));
marker.setSnippet(jsonArray.getString(2) + " " + jsonArray.getString(8));
}
}
} catch (JSONException e) {
}
My question is, what is the best solution here, store the points in a MySQL server and generate nearest shops from that area (SQlite Getting nearest locations (with latitude and longitude) something like this), or always query the server for the data. Or maybe a hybrid of both (query the server, then save the data in an SQLite db.)
I'm only a beginner in Android so sorry if this question is simple.
The fastest way should be to save the data in an SQLite db and query it from there, but if you only need the few shops that are near the user, it should be fine to simply call the web service every time.
Other than that, the freezing that occurs in your app is most likely due to the onPostExecute Method being called in the UI-Thread and you doing heavy work in this method.
You should not parse your JSON there, but rather in the doInBackground method and for each parsed element call publishProgress that calls the onProgressUpdate Method (which is also executed in the UI-Thread.
Like this, you can handle setting one single marker on the map at a time and that way, the time between the single onProgressUpdate calls can be used by the system to update the UI and so the freezing should no longer occur.
It should look somewhat like this:
protected Void doInBackground(...) {
String result = getResult();
try {
JSONArray jsonArray = new JSONArray(result);
String finalReturn[] = result.split("\\r?\\n");
if(jsonArray.get(0).toString().equals("4")) {
for (int i = 1; i < finalReturn.length; i++) {
jsonArray = new JSONArray(finalReturn[i]);
publishProgress(jsonArray);
}
}
} catch (JSONException e) {
//handle error
}
}
#Override
protected void onProgressUpdate(JSONArray... progress) {
JSONArray array = progress[0];
IconGenerator iconGenerator = new IconGenerator(getApplicationContext());
iconGenerator.setStyle(IconGenerator.STYLE_RED);
iconGenerator.setRotation(90);
iconGenerator.setContentRotation(-90);
Bitmap iconBitmap = iconGenerator.makeIcon(jsonArray.get(5).toString());
Marker marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(jsonArray.getDouble(6), jsonArray.getDouble(7)))
.icon(BitmapDescriptorFactory.fromBitmap(iconBitmap)));
marker.setTitle(jsonArray.getString(1));
marker.setSnippet(jsonArray.getString(2) + " " + jsonArray.getString(8));
}
Related
I am very new to Java programming, I would appreciate any kind of help.
So I want to display a set of lat-long coordinates (more than 50 coordinates) in Java-based canvas (e.g JFrame, Processing) from a WFS server. I have managed to parse lat-long value and print it to the console. Now I'm stuck in how to bring the lat-long coordinates to the screen coordinates (I'd like to draw it on 1000x500 size). I've tried to search for the reference but couldn't find the simplest one for a beginner like me. Here is the current part of my code :
String[] splitc = coord.split(",");
String lon = splitc[0];
String lat = splitc[1];
//parse string to float
float loncoord=Float.parseFloat(lon);
float latcoord=Float.parseFloat(lat);
Can I transfer the coordinates from the WFS to screen coordinates using world2screen.translate of Geotools library as in https://docs.geotools.org/latest/userguide/library/referencing/axis.html ?
In processing, there is a map() function (https://processing.org/reference/map_.html) to transfer from a range to another. I've tried it but it didn't work on my IDE.
One super noob question, I'm trying to store the WFS connection in a function so I can call it in another class, should I store it in static void or use "return"?
If someone can provide an example of a similar task, that would be very helpful. Thanks (Sara)
You can use this formula instead:
float x = ((WIDTH/360.0) * (180 + loncoord));
float y = ((HEIGHT/180.0) * (90 - latcoord));
It should work... Note that it returns a float and takes 5 arguments of the form:
map(input, inputMin, inputMax, outputMin, outputMax)
You only want to create the connection once, so you're left with two viable options: defining the connection as a static variable of a static class, or defining the connection as an instance variable of a class following the singleton pattern.
Assuming you chose the former approach, the method that returns the connection variable should therefore be static but not void:
public static connectionType getConnection() {
return connectionObject;
}
... where connectionType is the datatype of the connection.
The easiest way is to create a GeoTools WFSDataStore, this code builds up the getCapabilities string if the user has given just a URL to the service endpoint and handles authentication if needed. The datastore is stored in a field of the class:
public FetchWFS(String url, String user, String passwd) throws IOException, URISyntaxException {
if (!user.isEmpty()) {
auth = true;
}
baseURL = new URL(url);
List<NameValuePair> nvp = URLEncodedUtils.parse(baseURL.toURI(), "UTF-8");
NameValuePair service = new BasicNameValuePair("service", "wfs");
NameValuePair request = new BasicNameValuePair("request", "getCapabilities");
NameValuePair version = new BasicNameValuePair("version", "2.0.0");
HashMap<String, NameValuePair> parts = new HashMap<>();
parts.put(service.getName(), service);
parts.put(request.getName(), request);
parts.put(version.getName(), version);
for (NameValuePair part : nvp) {
if (part.getName().equalsIgnoreCase("SERVICE")) {
// We don't care what they think this should be
} else if (part.getName().equalsIgnoreCase("REQUEST")) {
// This must be getCapabuilities so we ignore them
} else if (part.getName().equalsIgnoreCase("VERSION")) {
System.out.println("Changing version to " + part.getValue());
parts.put(version.getName(), part);
} else {
parts.put(part.getName(), part);
}
}
URIBuilder builder = new URIBuilder();
builder.setScheme(baseURL.getProtocol());
builder.setHost(baseURL.getHost());
builder.setPort(baseURL.getPort());
builder.setPath(baseURL.getPath());
List<NameValuePair> p = new ArrayList<>();
p.addAll(parts.values());
builder.setParameters(p);
// builder.addParameter("viewparams", "q:\"mySolrQuery\"");
URI uri = builder.build();
System.out.println(uri);
baseURL = uri.toURL();
// fetch the DataStore
Map<String, Object> params = new HashMap<>();
params.put(WFSDataStoreFactory.URL.key, baseURL);
// params.put(WFSDataStoreFactory.WFS_STRATEGY.key, "mapserver");
if (auth) {
params.put(WFSDataStoreFactory.USERNAME.key, user);
params.put(WFSDataStoreFactory.PASSWORD.key, passwd);
}
// params.put(WFSDataStoreFactory.WFS_STRATEGY.key, "mapserver");
datastore = DataStoreFinder.getDataStore(params);
}
Once you have a DataStore (of any type) you can get a list of available
featureTypes and then add one (or more) of them to a map:
JMapFrame frame = new JMapFrame();
MapContent map = new MapContent();
String[] names = datastore.getNames();
featureSource = store.getFeatureSource(names[0]); //fetch first featureType
schema = featureSource.getSchema();
Style style = SLD.createSimpleStyle(schema);
this.layer = new FeatureLayer(featureSource, style);
map.addLayer(layer);
frame.enableToolBar(true);
frame.setMinimumSize(new Dimension(800, 400));
frame.setVisible(true);
The GeoTools Quickstart Tutorial will help you get started with simple mapping, and the Map Styling tutorial will allow you to generate a prettier map when you want more than a simple black and white default map.
My android app connects to Firebase and pulls "Alert Objects" that are sent there by my server.
When I export the data from Firebase, I get a beautifully formated JSON representation of the data.
Problem:
When I pull the data to my android device using a DataSnapshot, the data has '=' (equals signs) instead of ':' (semicolons). Also the quotations are not there.
When I try to do something like JSONObject alert = new JSONObject(data.getValue().toString()); I get errors for obvious reasons. I say obvious because if you look at what my code prints to the console you can see that it is no longer in valid JSON format.
A friend mentioned that I need to do something with encoding but we didn't have time to discuss it.
How can I iterate through these (kinda weird) Alert Objects that I have created and turn them into JSON objects within my Java so that I can access their properties like alert.date and alert.message.
I thought screenshots would help you see what I am doing. The firebase is not secured at all so you can feel free to take a look at it. It won't really do much and when I go to production I will be moving it anyways.
I am sure this is a super easy question to answer, I am just not too well versed with JSON and encoding as a whole.
Thanks!
you can it using gson library
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
/*JSONObject jsonObject = null;
try {
jsonObject=new JSONObject();
} catch (JSONException e) {
e.printStackTrace();
}*/
Gson gson = new Gson();
String s1 = gson.toJson(dataSnapshot.getValue());
JSONArray object = null;
try {
object = new JSONArray(s1);
} catch (JSONException e) {
e.printStackTrace();
}
JSONArray jsonArray = object;
Log.e("string", s1);
}
You cannot access JSON natively in Java.
But the Firebase DataSnapshot class provides everything you need.
If you have a DataSnapshot of the data at the fbAlerts in your screenshot, you can print the date+message and recipients for each:
for (DataSnapshot alert: alerts.getChildren()) {
System.out.println(alert.child("date").getValue();
System.out.println(alert.child("message").getValue();
for (DataSnapshot recipient: alert.child("recipients").getChildren()) {
System.out.println(recipient.child("name").getValue();
}
}
Alternatively, you can build a Java class that represents an alert. See the Firebase guide on reading data in Android for examples of that.
Use this way to convert the jsonObject form the dataSnapshot
Map<String, String> value = (Map<String, String>) dataSnapshot.getValue();
Log.i("dataSnapshot", "dataSnapshot" + new JSONObject(value));
From the above code extract, it looks like you have a JSONArray rather than a JSONObject.
In which case, you need to do something like the following:
// Find the right array object
JSONArray jsonArray = response.getJSONArray("fbAlerts");
// Loop through the array
for (int i=0; i< jsonArray.length(); i++) {
JSONObject myObj = jsonArray.getJSONObject(i);
strMsg = myObj.getString("message");
}
In the example - when you have repeating groups, this would seem to indicate an array and therefore needs an iterator to access the object contents.
In my endWorkout.java file, I am saving data into my Parse database using the following logic:
// Parse Storage
ParseObject testObject = new ParseObject("TestOne");
testObject.put("Device", ParseInstallation.getCurrentInstallation());
testObject.put("Reps", inputList);
testObject.saveInBackground();
Where I am first storing my Device ID for authentication purposes, and then storing inputList which is an ArrayList of integers.
In my Parse database, the data is properly saved, as shown below:
Now in my MainActivity.java, I would like to retrieve all the data in the Reps field of the Parse database for a single device. For example, the device yhmrKgokfS has 6 Arrays in the Parse database, I would like to sequentially retrieve each of them to display in a ListView on the screen.
Here is the logic I am trying to use:
List<ParseObject> importList = new ArrayList<ParseObject>();
//parse import list
ParseQuery<ParseObject> query = ParseQuery.getQuery("TestOne");
query.whereEqualTo("Device", ParseInstallation.getCurrentInstallation());
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> repList, ParseException e) {
if (e == null) {
Log.d("Reps", "Retrieved " + repList.size() + " reps");
} else {
Log.d("Reps", "Error: " + e.getMessage());
}
}
});
importList = repList;
I first want to make sure I'm importing from the current device, so I need to check if the Device field matches ParseInstallation.getCurrentInstallation(). Then I want to go ahead and get the first Reps array. However the last line importList = repList; does not work.
How can I go about achieving what I'm trying to do?
query.findInBackground works in asynchronous way. In other words, the line that you set the importList is executed after the line query.findInBackground. However, the query.findInBackground will make a network call that takes time. So if you want to use the repList when it is ready, you have to use it in done method where you are use the network call is done. Hope this helps.
Regards.
As #kinkspeech mentioned you need to move your line importList = repList; to your callback. And I suggest that you change it as follows:
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> repList, ParseException e) {
if (e == null) {
Log.d("Reps", "Retrieved " + repList.size() + " reps");
importList.addAll(replist);
} else {
Log.d("Reps", "Error: " + e.getMessage());
}
}
});
I realize my questions have been asked a lot but I have spent a considerable amount of time scouring both SO and google trying to get a better understanding of this concept with no success. I've seen many different implementations, which is what leads me to get some advice about my specific situation.
MY OBJECTIVE
I need to perform a post request to a php file and the goal is to ultimately populate fields in a list activity with some of the json data.
HTTP POST RESPONSE
Here is the format of the response data I'm getting back from the server, which appears to be a JSON object of arrays(?).
{"expense":[{"cat_id_PK":237,"cat_name":"Name1","cat_amount":"100.00","is_recurring":0},
{"cat_id_PK":238,"cat_name":"Name2","cat_amount":"200.00","is_recurring":0},
{"cat_id_PK":239,"cat_name":"Name3","cat_amount":"300.00","is_recurring":0},
{"cat_id_PK":240,"cat_name":"Name4","cat_amount":"400.00","is_recurring":0}],
"expense_rec": [{"cat_id_PK":207,"cat_name":"Name5","cat_amount":"500.00","is_recurring":1}]}
FIRST QUESTION
The code below is what I'm using to read the response. Is this how I should be handling that? It seems weird to get a json encoded response and then change it to a string, only to try and access elements of a json object again. Am I on the wrong track here?
//This code is in the doInBackground method of my "sendPostRequest" async task.
HttpResponse httpResponse = httpClient.execute(httpPost);
InputStream inputStream = httpResponse.getEntity().getContent();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String bufferedStrChunk = null;
while ((bufferedStrChunk = bufferedReader.readLine()) != null) {
stringBuilder.append(bufferedStrChunk);
}
//Returns string to onPostExecute()
return stringBuilder.toString();
SECOND QUESTION
I have another file called "PostResponse.java" that holds the following code I modeled after a tutorial online. I'm unsure of how to interact with this class from the onPostExecute method. How can I access say, the first item in the first object (something like in PHP where you could do: expense[0]['cat_name']). I've tried to do this various ways with no success. Here is the PostResponse.java class:
public class PostResponse {
public Integer cat_id_PK;
public String cat_name;
public BigDecimal cat_amount;
public Integer is_recurring;
public int getID() {
return this.cat_id_PK;
}
public void setID(int cat_id_PK){
this.cat_id_PK = cat_id_PK;
}
public String getName() {
return this.cat_name;
}
public void setName(String cat_name) {
this.cat_name = cat_name;
}
public BigDecimal getAmount() {
return this.cat_amount;
}
public void setAmount(BigDecimal cat_amount) {
this.cat_amount = cat_amount;
}
public int getRecurring() {
return this.is_recurring;
}
public void setRecurring(int is_recurring) {
this.is_recurring = is_recurring;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("*** Categories ***");
sb.append("cat_id_PK="+getID()+"\n");
sb.append("cat_name="+getName()+"\n");
sb.append("cat_amount="+getAmount()+"\n");
sb.append("is_recurring="+getRecurring()+"\n");
return sb.toString();
}
}
and here is the content of my onPostExecute method:
protected void onPostExecute(String result) {
super.onPostExecute(result);
Gson gson = new Gson();
PostResponse response = gson.fromJson(result, PostResponse.class);
System.out.println(result);
}
Like I said originally, my ultimate goal is to populate these items to a list activity, but at this point I'd settle for just knowing how to get at specific elements. However, if anyone would like to include how to populate a list activity in their response, it would save me a lot more headaches, as nothing with java is coming easy for me!
FIRST QUESTION
The code below is what I'm using to read the response. Is this how I should be handling that? It seems weird to get a json encoded response and then change it to a string, only to try and access elements of a json object again. Am I on the wrong track here?
It's one way of handling the http response. A "json encoded response" is little more than a text-based response, so converting it into a string on the receiving end would make sense. That is, the json you receive isn't an 'object' as far as Java is concerned: it's just textual representation of an object (or a bunch of objects in your case), received as a stream of bytes.
That being said, you can potentially shorten your code by skipping the string(builder) part. Gson provides an alternative constructor that takes a Reader instance, for which you can suppy the BufferedReader in your code snippet.
As a side note: the conversion of textual json into Java objects is a potentially 'heavy' operation. As such, you'd best avoid doing it on the main/ui thread, so just move it into the doInBackground() method of your AsyncTask (and change types appropriately).
SECOND QUESTION
I have another file called "PostResponse.java" that holds the following code I modeled after a tutorial online. I'm unsure of how to interact with this class from the onPostExecute method. How can I access say, the first item in the first object (something like in PHP where you could do: expense[0]['cat_name']). I've tried to do this various ways with no success.
You're close, but if you look more closely to the json sample, you'll see that your PostResponse class is not a good match for it:
{
"expense": [
{
"cat_id_PK": 237,
"cat_name": "Name1",
"cat_amount": "100.00",
"is_recurring": 0
},
{
"cat_id_PK": 238,
"cat_name": "Name2",
"cat_amount": "200.00",
"is_recurring": 0
},
{
"cat_id_PK": 239,
"cat_name": "Name3",
"cat_amount": "300.00",
"is_recurring": 0
},
{
"cat_id_PK": 240,
"cat_name": "Name4",
"cat_amount": "400.00",
"is_recurring": 0
}
],
"expense_rec": [
{
"cat_id_PK": 207,
"cat_name": "Name5",
"cat_amount": "500.00",
"is_recurring": 1
}
]
}
Consider the more hierarchical formatting above. On the first level there are two (json) objects: expense and expense_rec (both contain 0...* elements, as the square brackets indicate). That means that whatever class you're going to be trying to map the json onto, should define these fields too. If you now look at your PostResponse class, it should become obvious that in its current form it in fact models one of the child objects of the aforementioned fields.
Basically, the classes to map the json onto, should look somewhat like this:
PostResponse:
public class PostResponse {
public ExpenseItem[] expense;
public ExpenseItem[] expense_rec;
// List<ExpenseItem> is also supported
// getters & setters
}
ExpenseItem:
public class ExpenseItem {
public Integer cat_id_PK;
public String cat_name;
public BigDecimal cat_amount;
public Integer is_recurring;
// getters & setters
}
With the model classes defined, try to let Gson work its magic again. If all goes well, you should be able to access the data in a way similar to what you're used to in PHP:
// map json to POJOs
PostResponse response = new Gson().fromJson(bufferedReader, PostResponse.class);
// retrieve the cat_name for the first item (assuming there is one)
String catName = response.getExpense()[0].getName();
... or any of the other fields through the getters defined in ExpenseItem.
Once you have this part working, it's going to be fairly straightforward to supply the array or list of expenses to an adapter (have a look at ArrayAdapter in the Android framenwork) and bind that adapter to a ListView.
The answer is yes, you will get the response in InputStream
For your second question check this out - jsonschema2pojo this can be helpful while creating models for your JSON data.
Then to use GSON
Gson gson = new Gson();
YourObj yourObj = (YourObj) gson.fromJson(result, YourObj.class);
The answer is yes.Response is received as InputSteam
protected void onPostExecute(String result)
{
super.onPostExecute(result);
Gson gson = new Gson();
PostResponse response = gson.fromJson(result, PostResponse.class);
System.out.println(result);
}
This code section mostly means that after an AsyncTask that get web Response and get the String format json response,this onPostExecute will be called with that Stringfied json.
Gson gson = new Gson();
Gson is a library supported by Google for android to deserialization into your class OBject.
gson.fromJson(result, PostResponse.class);
This method is the real process of deserialization. result is Stringfied json and the second is the Target class you want to deserialize into.
This will return a PostResponse Object and you can use it now.
For the json data (
{"expense":[{"cat_id_PK":237,"cat_name":"Name1","cat_amount":"100.00","is_recurring":0},
{"cat_id_PK":238,"cat_name":"Name2","cat_amount":"200.00","is_recurring":0},
{"cat_id_PK":239,"cat_name":"Name3","cat_amount":"300.00","is_recurring":0},
{"cat_id_PK":240,"cat_name":"Name4","cat_amount":"400.00","is_recurring":0}],
"expense_rec": [{"cat_id_PK":207,"cat_name":"Name5","cat_amount":"500.00","is_recurring":1}]}),
it contains two different arrays here, one is "expense" and another is "expense_rec". So if you want to populate these items to a list activity, you can try the follow methods.
protected void onPostExecute(String result) {
super.onPostExecute(result);
JSONObject jsonObject = new JSONObject(builder.toString());
Log.i(TAG, "jsonObject is : " + jsonObject.toString());
//this is the first array data
JSONArray jsonArray = jsonObject.getJSONArray("expense");
Log.i(TAG, "Array length is: " + jsonArray.length());
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsoObj = jsonArray.getJSONObject(i);
String name = jsoObj.getString("cat_name");
Log.i(TAG, "file name is: " + name);
}
//this is the second array data
jsonArray = jsonObject.getJSONArray("expense_rec");
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsoObj = jsonArray.getJSONObject(i);
String name = jsoObj.getString("cat_name");
Log.i(TAG, "file name is: " + name);
}
}
I have used the HSQLDB for storing the data in my app. I make 15 Web service call one by one. and store the data in DB. It's working fine for medimum amount of data. I got the OME(Out of memory error) for large data. I mean, suppose I am having like 20k records for web service method.So we are getting the OME while storing the data into the DB. I tried with profiler feature also but I am unable to find which object was consumed more heap memory. So I struck here. I need the somebody help to solve this.
Code
try {
JSONObject jSONObject = getJSONData(clientId, ApplicationConstants.REST_METHOD_GET_ALL_CATEGORIES_LIST_BY_CLIENT_ID);
if (jSONObject != null) {
JSONArray jSONArray = jSONObject.getJSONArray(ApplicationConstants.JSON_OBJECT_RESPONSE);
Integer length = jSONArray.length();
if (length == 0) {
if (_logger.isInfoEnabled()) {
_logger.info("Categories not found for client {}", clientId);
}
} else {
if (_logger.isInfoEnabled()) {
_logger.info("{} Categories found for client {}", length, clientId);
}
SyncDao synDao = (SyncDao) getDAO(ApplicationConstants.REST_SYNC_DAO);
for (int i = 0; i < length; i++) {
JSONObject jSONObj = jSONArray.getJSONObject(i);
ProjectMenu projectMenu = new ProjectMenu();
projectMenu.setClientId(clientId);
projectMenu.setCategory(ApplicationConstants.PROJECT_MENU_CATEGORY_SUB_MENU);
projectMenu.setCategoryType(ApplicationConstants.CATEGORY_TYPE_CATEGORY);
projectMenu.setCreatedDate(jSONObj.getString(ApplicationConstants.REST_CATEGORY_CREATED_DATE));
projectMenu.setElementId(jSONObj.getString(ApplicationConstants.REST_CATEGORY_ID));
projectMenu.setIsLeaf(Boolean.FALSE);
projectMenu.setLabel(jSONObj.getString(ApplicationConstants.REST_CATEGORY_NUMBER));
projectMenu.setLevel(new Integer(4));
projectMenu.setSortOrder(jSONObj.getInt(ApplicationConstants.REST_CATEGORY_SORT_ORDER));
// Getting parent menu details
ProjectMenu parentProjectMenu = synDao.getProjectMenu(clientId,
jSONObj.getString(ApplicationConstants.REST_CATEGORY_PROJECT_COMPONENT_ID), ApplicationConstants.CATEGORY_TYPE_COMPONENT);
if (parentProjectMenu != null) {
if (ApplicationConstants.REST_NO_COMPONENT_LABEL.equalsIgnoreCase(parentProjectMenu.getLabel())) {
projectMenu.setParentMenuId(parentProjectMenu.getParentMenuId());
} else {
projectMenu.setParentMenuId(parentProjectMenu.getId());
}
projectMenu.setProjectId(parentProjectMenu.getProjectId());
}
if (_logger.isDebugEnabled()) {
_logger.debug("Persisting Category: {}", projectMenu.toString());
}
synDao.persist(projectMenu);
}
}
}
} catch (JSONException jsonex) {
if (_logger.isErrorEnabled()) {
_logger.error("Exception while synchronizing Categories.", jsonex);
}
}
Use of MEMORY tables is often the cause for OOM errors when the amount of data in the database gets larger.
Convert the tables that hold large amounts of data to CACHED tables and there won't be any more OOM errors.
SET TABLE t TYPE CACHED