My Spring Boot application uses JDBCTemplate to send SQL queries to a PostgreSQL Database. It seems that each time a connection is got from the pool by the template, the connection is never released. The number of active connections (datasource.primary.active) is always increasing.
In the logs, after SQL Query using JDBCTemplate, I can see :
DEBUG o.s.j.d.DataSourceUtils - Returning JDBC Connection to DataSource
But the count of idle connection stay with the same value and the count of active connections is not decreasing. When the maximum value is reached, it becomes impossible to retrieve a connection to execute a query.
So, I think there is no return of the connection to the datasource pool, any idea please ?
Here is the datasource configuration got with Actuator :
"dataSource": {
"prefix": "spring.datasource.tomcat",
"properties": {
"connectionProperties": null,
"propagateInterruptState": false,
"validator": null,
"useDisposableConnectionFacade": true,
"defaultCatalog": null,
"validationInterval": 3000,
"jmxEnabled": true,
"ignoreExceptionOnPreLoad": false,
"logAbandoned": false,
"commitOnReturn": false,
"password": "******",
"maxIdle": 100,
"testWhileIdle": false,
"removeAbandoned": false,
"poolProperties": {
"dbProperties": {
"user": "postgres",
"password": "******"
},
"url": "jdbc:postgresql://localhost:5432/tvir",
"driverClassName": "org.postgresql.Driver",
"defaultAutoCommit": null,
"defaultReadOnly": null,
"defaultTransactionIsolation": -1,
"defaultCatalog": null,
"connectionProperties": null,
"initialSize": 10,
"maxActive": 100,
"maxIdle": 100,
"minIdle": 10,
"maxWait": 30000,
"validationQuery": "SELECT 1",
"validationQueryTimeout": -1,
"validatorClassName": null,
"validator": null,
"testOnBorrow": true,
"testOnReturn": false,
"testWhileIdle": false,
"timeBetweenEvictionRunsMillis": 5000,
"numTestsPerEvictionRun": 0,
"minEvictableIdleTimeMillis": 60000,
"accessToUnderlyingConnectionAllowed": true,
"removeAbandoned": false,
"removeAbandonedTimeout": 60,
"logAbandoned": false,
"name": "Tomcat Connection Pool[1-574817798]",
"password": "******",
"username": "postgres",
"validationInterval": 3000,
"jmxEnabled": true,
"initSQL": null,
"testOnConnect": false,
"jdbcInterceptors": null,
"fairQueue": true,
"useEquals": true,
"abandonWhenPercentageFull": 0,
"maxAge": 0,
"useLock": false,
"suspectTimeout": 0,
"dataSource": null,
"dataSourceJNDI": null,
"alternateUsernameAllowed": false,
"commitOnReturn": false,
"rollbackOnReturn": false,
"useDisposableConnectionFacade": true,
"logValidationErrors": false,
"propagateInterruptState": false,
"ignoreExceptionOnPreLoad": false,
"useStatementFacade": true
},
And the code used to query the db :
JdbcTemplate jdbcTemplate = appCtx.getBean(JdbcTemplate.class);
ResultSet columns = jdbcTemplate.getDataSource().getConnection().getMetaData().getColumns(null, null, source.getTable().toLowerCase(), null);
String selectList = "";
while (columns.next())
{
String colName = columns.getString("COLUMN_NAME");
String colType = columns.getString("DATA_TYPE");
if(!selectList.equals("")) {
selectList += ", ";
}
if((""+java.sql.Types.INTEGER).equalsIgnoreCase(colType) ||
(""+java.sql.Types.DOUBLE).equalsIgnoreCase(colType) ||
(""+java.sql.Types.BIGINT).equalsIgnoreCase(colType) ||
(""+java.sql.Types.FLOAT).equalsIgnoreCase(colType) ) {
selectList += "SUM(" + colName + ")";
} else {
selectList += "MAX(" + colName + ")";
}
selectList += " AS "+colName;
}
String sql = "SELECT "+selectList+" FROM "+source.getTable()+" "+
"WHERE "+source.getDateColumn()+" >= ? "+
"AND "+source.getDateColumn()+" <= ? ";
List<Map<String, Object>> results = jdbcTemplate.queryForList(sql, Date.valueOf(startDate), Date.valueOf(endDate));
Spring boot let you configure how you want your datasource to behave.
You will find a full list on the official doc.
check the following properties for your case :
spring.datasource.maxActive
spring.datasource.maxIdle
Depending on what connection pool you are using you can also tune it using spring boot properties (everything is in the doc) .
Related
I have model class as follows :
public class ItemAdditionalInfo extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#NotNull(groups = Existing.class)
#Null(groups = New.class)
private Long itemAdditionalInfoId;
#NotNull
#Column(nullable = false)
private Integer itemNbr;
private String itemDescription;
private Integer mdsFamId;
private Integer deptNbr;
private String deptDesc;
private Integer subcatNbr;
private String subcatDesc;
private Double retailPrice;
etc...
}
public class DecileConfig extends BaseEntity {
#Id
#GeneratedValue(generator = "uuid")
#Null(groups = New.class)
private String id;
private Boolean decileMode;
private String decileCalculatorType;
private String decileLevelType;
private Integer decileLevelNumber;
private Integer forecastRange;
etc...
}
public class ItemAdditionalDecileGetDTO {
private ItemAdditionalInfo itemAdditionalInfo;
private DecileConfig decileConfig;
}
Now while testing... I am supposed to get ItemAdditionalDecileGetDTO object and I need test some of its fields in ItemAdditionalInfo.
So I wrote something like this :
MvcResult result = mockMvc.perform(requestBuilder)
.andReturn();
MockHttpServletResponse response = result.getResponse();
ServiceResponse sr =gson.fromJson(response.getContentAsString(), ServiceResponse.class);
System.out.println("SR Obj "+sr);
List<ItemAdditionalDecileGetDTO> responeList = (List<ItemAdditionalDecileGetDTO>)sr.getData();//even though its type casted but its actually gson.LinkedTreeMap
String json = gson.toJsonTree(responeList.get(0)).getAsJsonObject().toString();
System.out.println("Json Obj "+json);
ItemAdditionalDecileGetDTO obj = gson.fromJson(json,ItemAdditionalDecileGetDTO.class);
System.out.println("Obtained IAdInfo "+obj);
assertEquals(123, java.util.Optional.of(obj.getItemAdditionalInfo().getItemNbr()));
I got ServiceResponse as Json as follows from this line "System.out.println("Json Obj "+json);":
{
"data": [
{
"itemAdditionalInfo": {
"createdBy": "s0r0e4g",
"createdOn": "2022-08-26T00:00:00Z",
"lastUpdatedBy": "admin",
"lastUpdatedOn": "2023-01-19T00:00:00Z",
"itemAdditionalInfoId": 9999,
"itemNbr": 123,
"itemDescription": "code01 23",
"mdsFamId": null,
"deptNbr": 202,
"deptDesc": null,
"subcatNbr": 100,
"subcatDesc": null,
"retailPrice": null,
"events": [
{
"end_date": "2022-12-24",
"event_name": "FY23 December ISB",
"event_status": "Past",
"start_date": "2022-11-30"
}
],
"imported": false,
"itemStatus": null,
"vendorNbrFull": null,
"originZipCode": null,
"vendorCommittedQty": null,
"vendorRemainingQty": null,
"palletTiQty": null,
"palletHiQty": null,
"vendorIncrementOrderQty": null,
"vendorPackQty": null,
"isBreakPack": null,
"histLikeItemNbr": null,
"secondaryLikeItemNbrs": null,
"inheritCategoryDecile": false,
"inheritSubcategoryDecile": true,
"isVLTRequired": true,
"isClubLevelParamPresent": true,
"overrideQty": null,
"minOrderQty": null,
"demandMultiplier": null,
"itemOnOverrideDate": null,
"itemOffOverrideDate": null,
"overrideQtyStatus": null,
"isRunning": null,
"maxOffShelfDate": "2023-02-01",
"minOnShelfDate": "2007-09-10",
"totalOnHand": null,
"totalOnOrder": null,
"leadTime": null,
"clubCountCdf": null,
"clubCountLegacy": null,
"sumNeedQtyCdf": null,
"sumNeedQtyLegacy": 2,
"totalDemandLegacy": null,
"allocationStatus": "Allocation available",
"allocationDescription": null,
"tenantId": "sams_us",
"seasonName": null,
"likeItemsWithEstimatedMultiplier": null
},
"decileConfig": {
"createdBy": "s0k06wm",
"createdOn": "2022-01-13T00:00:00Z",
"lastUpdatedBy": "admin",
"lastUpdatedOn": "2023-01-18T00:00:00Z",
"id": "63081ab2d6e1a61d443d8483",
"decileMode": false,
"decileCalculatorType": "test",
"decileLevelType": "subcat-202",
"decileLevelNumber": 100,
"forecastRange": 4,
"decileCalculatorParameters": [
{
"decileCalculatorParameterKey": "sales",
"decileCalculatorParameterValue": "50"
},
{
"decileCalculatorParameterKey": "profit",
"decileCalculatorParameterValue": "50"
},
{
"decileCalculatorParameterKey": "from",
"decileCalculatorParameterValue": "2021-01-01"
},
{
"decileCalculatorParameterKey": "to",
"decileCalculatorParameterValue": "2021-03-01"
}
],
"decileConfiguration": null,
"globalDecileConfiguration": {
"decileNo": "1",
"minPres": "1",
"wosTarget": "2",
"maxClubQty": "5",
"oosThreshold": "0"
},
"tenantId": "sams_us"
}
}
],
"errors": null,
"metadata": null,
"status": null,
"pageable": {
"totalPages": 1,
"totalElements": 1,
"pageSize": 10,
"pageNumber": 0,
"numberOfElements": 1
}
}
But I got this exception :
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected BEGIN_OBJECT but was STRING at line 1 column 59 path
$.itemAdditionalInfo.createdOn.
As it could not parse this line :
ItemAdditionalDecileGetDTO obj = gson.fromJson(json,ItemAdditionalDecileGetDTO.class);
FYI createdOn and lastUpdatedOn is being populated by DB and I have no control over it and its a DateTime of type.
I have json with dynamic range which is groving all the time.
{
"payload": {
"totalCount": 302,
"items": [
{
"id": 1379,
"date": "2021-04-08T17:06:03+02:00",
"name": "Newcastle United Aston Villa",
"externalId": "2",
"mediaTag": null,
"deleted": false,
"originalId": null,
"cancelled": false,
"relatedEventsOrderIndex": []
},
{
"id": 1380,
"date": "2021-04-08T17:06:03+02:00",
"name": "Arsenal Tottenham Hotspur",
"externalId": "3",
"mediaTag": null,
"deleted": false,
"originalId": null,
"cancelled": false,
"relatedEventsOrderIndex": []
}
]
},
"errorCode": 0,
"errorTimeStamp": null,
"errorMessage": null,
"hasError": false
}
I can extract all the values like
And if i use as: ID1_1, ID1_2.......ID1_100 -> its working fine.
But, I want to output in the logger.
If I tried as:
def IDS = vars.getObject("ID1");
for (int i=0; i>IDS.length; i++) {
log.warn("ID as: " + IDS + (i + 1) );
}
I got: Cannot get property 'length' on null object
How can I output all the ID, from dynamic JSON?
I don't think you have ID1 variable, you have ID1_1, ID1_2 .... and ID1_matchNr which holds the number of matches, you can see it yourself using Debug Sampler
You need to change your code as:
for (int i = 1; i <= vars.get('ID1_matchNr') as int; i++) {
log.warn("ID as: " + vars.get("ID1_" + i));
}
in the above code vars stands for JMeterVariables class instance
It should be something like this (pseudo code)
for (int i=0; i>IDS.length; i++) {
log.warn("ID as: " + vars.get("ID1_" + i.toString() );
}
each of the ID1_1, ID1_2.......ID1_100 are variables. You can verify that using a Debug Sampler
I have an array of objects named Employees and am trying to get the ones who are department_id=3 and I don't want to go back to laravel and make another request so is there a way to do so with vuex?
"id": 25,
"name": "name",
"email": "name#gmail.com",
"last_name": "lastname",
"phone": "98745632",
"gender": "Male",
"nationality": "Tunisian",
"school": "ISIMM",
"experience_level": "2",
"source": "Linkedin",
"hiring_date": "2020-04-17",
"end_contract": "2020-04-18",
"position": "web developer",
"grade": "Junior",
"contract": "Cdi",
"department_id": 1,
"company_id": 1,
"archived": "0",
"img": null,
"supervisor_id": 1,
"ipAdress": null,
"last_login_at": null,
"department": {
"id": 1,
"name": "mobile"
},
here's
state :
const employee = {
state: {
Employees: [],
sysAdmins: [],
},
here's
getters :
sysAdmins: (state) =>
state.Employees.map((element) => (element.department_id = "3")),
Employees: (state) => state.Employees,
here's
mutations :
getsysAdmins(state, employees) {
state.sysAdmins = employees;
},
getEmployees(state, employees) {
state.Employees = employees;
},
here's
actions :
getEmployees(context) {
const config = {
headers: {
"x-api-key": process.env.VUE_APP_SIRH_X_API_KEY,
Authorization: localStorage.getItem("access_token"),
},
};
return new Promise((resolve, reject) => {
axios
.get("/employees/all_employees", config)
.then((response) => {
context.commit("getEmployees", response.data.data.users);
context.commit("getsysAdmins", response.data.data.users);
resolve(response);
})
.catch((error) => {
reject(error);
});
});
},
If I understand it right, you want to return the while Employee Object for those employees that work in a certain department.
You can do this by filtering your Employees array. I would write that as following:
getters: {
employees: (state) => state.Employees,
sysAdmins: (state) => state.Employees.filter((employee) => employee.department_id === 3),
// If your DB returns a string as the department_id, you'll have to check against "3"
}
If sysAdmins is always a subset of the employees, it makes more sense to always use a getter instead of placing these in a separate array in the state.
Some other notes:
- You mutations are called get... while these are setters, it might be best to rename these.
- In your action, you currently set the same result as employees and sysAdmins. Again, I would just set employees and always filter the sysAdmins from that array.
try this..
check the result using console.log to make it sure.
const newValue = {
...JSON.parse(localStorage.getItem("Employees")),
department.id: 3
}
localStorage.setItem("Employees", JSON.stringify(newValue))
or
// Get the user from localStorage and parse into object
let department = JSON.parse(localStorage.getItem("Employees"));
// Update an attribute on the user object
Employees.department.id = 2;
// Update the user in localStorage and stringify to string
localStorage.setItem("Employees", JSON.stringify(Employees));
it seems that SpringData ES don't provide classes to fetch highlights returned by ES. Spring Data can return Lists of Objects but the highlights sections in the Json returned by ES is in a separated part that is not handled by the "ElasticSearchTemplate" class.
Code example :-
QueryBuilder query = QueryBuilders.matchQuery("name","tom");
SearchQuery searchQuery =new NativeSearchQueryBuilder().withQuery(query).
with HighlightFields(new Field("name")).build();
List<ESDocument> publications = elasticsearchTemplate.queryForList
(searchQuery, ESDocument.class);
I might be wrong, but I can't figure out to do only with SpringDataES. Someone can post an example of how we can get highlights with Spring Data ES ?
Thanks in advance !
From the test cases in spring data elasticsearch I've found solution to this :
This can be helpful.
#Test
public void shouldReturnHighlightedFieldsForGivenQueryAndFields() {
//given
String documentId = randomNumeric(5);
String actualMessage = "some test message";
String highlightedMessage = "some <em>test</em> message";
SampleEntity sampleEntity = SampleEntity.builder().id(documentId)
.message(actualMessage)
.version(System.currentTimeMillis()).build();
IndexQuery indexQuery = getIndexQuery(sampleEntity);
elasticsearchTemplate.index(indexQuery);
elasticsearchTemplate.refresh(SampleEntity.class);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(termQuery("message", "test"))
.withHighlightFields(new HighlightBuilder.Field("message"))
.build();
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, new SearchResultMapper() {
#Override
public <T> Page<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
List<SampleEntity> chunk = new ArrayList<SampleEntity>();
for (SearchHit searchHit : response.getHits()) {
if (response.getHits().getHits().length <= 0) {
return null;
}
SampleEntity user = new SampleEntity();
user.setId(searchHit.getId());
user.setMessage((String) searchHit.getSource().get("message"));
user.setHighlightedMessage(searchHit.getHighlightFields().get("message").fragments()[0].toString());
chunk.add(user);
}
if (chunk.size() > 0) {
return new PageImpl<T>((List<T>) chunk);
}
return null;
}
});
assertThat(sampleEntities.getContent().get(0).getHighlightedMessage(), is(highlightedMessage));
}
Spring Data Elasticsearch 4.0 now has the SearchPage result type, which makes things a little easier if we need to return highlighted results:
This is a working sample:
String query = "(id:123 OR id:456) AND (database:UCLF) AND (services:(sealer?), services:electronic*)"
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withPageable(pageable)
.withQuery(queryStringQuery(query))
.withSourceFilter(sourceFilter)
.withHighlightFields(new HighlightBuilder.Field("goodsAndServices"))
.build();
SearchHits<Trademark> searchHits = template.search(searchQuery, Trademark.class, IndexCoordinates.of("trademark"));
SearchPage<Trademark> page = SearchHitSupport.searchPageFor(searchHits, searchQuery.getPageable());
return (Page<Trademark>) SearchHitSupport.unwrapSearchHits(page);
And this would be the response from Page object in json:
{
"content": [
{
"id": "123",
"score": 12.10748,
"sortValues": [],
"content": {
"_id": "1P0XzXIBdRyrchmFplEA",
"trademarkIdentifier": "abc234",
"goodsAndServices": null,
"language": "EN",
"niceClass": "2",
"sequence": null,
"database": "UCLF",
"taggedResult": null
},
"highlightFields": {
"goodsAndServices": [
"VARNISHES, <em>SEALERS</em>, AND NATURAL WOOD FINISHES"
]
}
}
],
"pageable": {
"sort": {
"unsorted": true,
"sorted": false,
"empty": true
},
"offset": 0,
"pageNumber": 0,
"pageSize": 20,
"unpaged": false,
"paged": true
},
"searchHits": {
"totalHits": 1,
"totalHitsRelation": "EQUAL_TO",
"maxScore": 12.10748,
"scrollId": null,
"searchHits": [
{
"id": "123",
"score": 12.10748,
"sortValues": [],
"content": {
"_id": "1P0XzXIBdRyrchmFplEA",
"trademarkIdentifier": "abc234",
"goodsAndServices": null,
"language": "EN",
"niceClass": "2",
"sequence": null,
"database": "UCLF",
"taggedResult": null
},
"highlightFields": {
"goodsAndServices": [
"VARNISHES, <em>SEALERS</em>, AND NATURAL WOOD FINISHES"
]
}
}
],
"aggregations": null,
"empty": false
},
"totalPages": 1,
"totalElements": 1,
"size": 20,
"number": 0,
"numberOfElements": 1,
"last": true,
"first": true,
"sort": {
"unsorted": true,
"sorted": false,
"empty": true
},
"empty": false
}
Actually, you could do the following, with a custom ResultExtractor:
QueryBuilder query = QueryBuilders.matchQuery("name", "tom");
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(query)
.withHighlightFields(new Field("name")).build();
return elasticsearchTemplate.query(searchQuery.build(), new CustomResultExtractor());
And then
public class CustomResultExtractor implements ResultsExtractor<List<MyClass>> {
private final DefaultEntityMapper defaultEntityMapper;
public CustomResultExtractor() {
defaultEntityMapper = new DefaultEntityMapper();
}
#Override
public List<MyClass> extract(SearchResponse response) {
return StreamSupport.stream(response.getHits().spliterator(), false)
.map(this::searchHitToMyClass)
.collect(Collectors.toList());
}
private MyClass searchHitToMyClass(SearchHit searchHit) {
MyElasticSearchObject myObject;
try {
myObject = defaultEntityMapper.mapToObject(searchHit.getSourceAsString(), MyElasticSearchObject.class);
} catch (IOException e) {
throw new ElasticsearchException("failed to map source [ " + searchHit.getSourceAsString() + "] to class " + MyElasticSearchObject.class.getSimpleName(), e);
}
List<String> highlights = searchHit.getHighlightFields().values()
.stream()
.flatMap(highlightField -> Arrays.stream(highlightField.fragments()))
.map(Text::string)
.collect(Collectors.toList());
// Or whatever you want to do with the highlights
return new MyClass(myObject, highlights);
}}
Note that I used a list but you could use any other iterable data structure. Also, you could do something else with the highlights. Here I'm simply listing them.
https://stackoverflow.com/a/37163711/6643675
The first answer does works,but I found some pageable problems with its returned result,which display with the wrong total elements and toalpages.Arter I checkout the DefaultResultMapper implementation, the returned statement shoud be return new AggregatedPageImpl((List<T>) chunk, pageable, totalHits, response.getAggregations(), response.getScrollId(), maxScore);,and then it works with paging.wish i could help you guys~
I have a project where I want to inline edit a value in a table generated via DataTables and am therefore using dataTables.editable
The table is rendering fine but when I try and to sumit an edit I get an error and if I look at the return value the id field is blank.
The controller action is as follows:
public ActionResult AjaxHandler(jQueryDataTableParamModel param)
{
var allMonthlyCosts = _unitOfWork.MonthlyCostRepository.Get(includeProperties: "Period, Employee");
IEnumerable<MonthlyCost> filteredMonthlyCosts;
if (!string.IsNullOrEmpty(param.sSearch))
{
filteredMonthlyCosts = _unitOfWork.MonthlyCostRepository.Get(includeProperties: "Period, Employee")
.Where(mc => mc.Period.Name.Contains(param.sSearch)
||
mc.Employee.ClockNo.Contains(param.sSearch));
}
else
{
filteredMonthlyCosts = allMonthlyCosts;
}
var displayedMonthlyCosts = filteredMonthlyCosts
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength);
var result = from mc in displayedMonthlyCosts
select new { ID = mc.Id, EvisionCost = mc.EvisionCost, EmployeeNo = mc.Employee.ClockNo, PeriodName = mc.Period.Name, TotalDays = mc.TotalDays, TotalCost = mc.TotalCost() };
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = allMonthlyCosts.Count(),
iTotalDisplayRecords = filteredMonthlyCosts.Count(),
aaData = result
},
JsonRequestBehavior.AllowGet);
}
The Javascript is as follows:
$('#myDataTable').dataTable({
"bServerSide": true,
"sAjaxSource": "MonthlyCost/AjaxHandler",
"bProcessing": true,
"aoColumns": [
{ "mData": "ID",
"bSearchable": false,
"bSortable": false,
"bVisible": false
},
{ "mData": "EvisionCost" },
{ "mData": "PeriodName" },
{ "mData": "EmployeeNo" },
{ "mData": "TotalDays" },
{ "mData": "TotalCost" }
]
}).makeEditable({
sUpdateURL: "/MonthlyCost/UpdateData",
"aoColumns": [
{},
null,
null,
null,
null]
});
The error I get is:
Cell cannot be #Updated(Server Error)
And the returned form is as follows:
value:2505
id:
rowId:0
columnPosition:0
columnId:1
columnName:EvisionCost
Issue is quite st.forward
Your editing is not reaching this plug-in code below . Thats why its throwing the error of your mention
CODE IN EDITABLE DATATABLE PLUGIN:
//Utility function used to apply editable plugin on table cells
function fnApplyEditable(aoNodes) {
var oDefaultEditableSettings = {
event: 'dblclick',
"callback": function (sValue, settings) {
properties.fnEndProcessingMode();
if (sNewCellValue == sValue) {
var aPos = oTable.fnGetPosition(this);
oTable.fnUpdate(sValue, aPos[0], aPos[2]);
} else {
var aPos = oTable.fnGetPosition(this);
oTable.fnUpdate(sOldValue, aPos[0], aPos[2]);
properties.fnShowError(sValue, "update");
}
},
"submitdata": function (value, settings) {
properties.fnStartProcessingMode();
sOldValue = value;
sNewCellValue = $("input,select", $(this)).val();
var id = fnGetCellID(this);
var rowId = oTable.fnGetPosition(this)[0];
var columnPosition = oTable.fnGetPosition(this)[1];
var columnId = oTable.fnGetPosition(this)[2];
var sColumnName = oTable.fnSettings().aoColumns[columnId].sName;
if (sColumnName == null || sColumnName == "")
sColumnName = oTable.fnSettings().aoColumns[columnId].sTitle;
return {
"id": id,
"rowId": rowId,
"columnPosition": columnPosition,
"columnId": columnId,
"columnName": sColumnName
};
},
"onerror": function () {
properties.fnEndProcessingMode();
properties.fnShowError("Cell cannot be updated(Server error)", "update");
},
"height": properties.height
};
This issue i am facing recently and i am trying like
<script type="text/javascript">
$(document).ready(function () {
$('#myDataTable').dataTable({ "bProcessing": true,
**"bServerSide": true,
"sAjaxSource": 'Home/AjaxHandler',
"sUpdateURL": '#Url.Action("UpdateData","Home")',
"sAddURL": '#Url.Action("AddData","Home")' ,
"sDeleteURL": '#Url.Action("DeleteData","Home")',**
"aoColumns": [
{ "sName": "ID",
"bSearchable": false,
"bSortable": false,
"bVisible": false
},
{ "sName": "Contact_Name" },
{ "sName": "Contact_Address" },
{ "sName": "Lead_Source" },
{ "sName": "Domain" },
]
}).makeEditable();
});
</script>
}
If this work please let me know . If you find any other way around do mention it . I am also in the same situation like you Finding answers
Regards