spring jpa won't update new data - spring

I would like to update new data from request.
Request JSON data looks like this.
[{"media_id : 1, "path" : "some path", ...}, {"media_id : 2, "path" : "some path", ...}]
These primary keys already exist in database
So It will update those rows and It should be updated
But update sql on debug log only update old data
I checked out media object that It contains new data from request
But jpa still try update with old data
What is my mistake?
private List<Media> upsertMedia(SquarePostDetailResource postToUpsert) {
List<Media> media = postToUpsert.getContent().getMedia();
media.forEach((item) -> {
item.setCreatedAt(item.getId() == null ? new Date() : item.getCreatedAt());
item.setModifiedAt(new Date());
item.setMember(Member.builder().id(postToUpsert.getMemberId()).build());
item.setSquare(Square.builder().id(postToUpsert.getSquareId()).build());
item.setSquarePost(SquarePost.builder().id(postToUpsert.getPostId()).build());
});
return (List<Media>) mediaRepo.save(media);
}

If you mean that updates inside foreach do not update the database, you can try the following.
private List<Media> upsertMedia(SquarePostDetailResource postToUpsert) {
List<Media> media = postToUpsert.getContent().getMedia();
List<Media> updatedMedia = new ArrayList<>();
media.forEach((item) -> {
item.setCreatedAt(item.getId() == null ? new Date() : item.getCreatedAt());
item.setModifiedAt(new Date());
item.setMember(Member.builder().id(postToUpsert.getMemberId()).build());
item.setSquare(Square.builder().id(postToUpsert.getSquareId()).build());
item.setSquarePost(SquarePost.builder().id(postToUpsert.getPostId()).build());
updatedMedia.add(item);
});
return (List<Media>) mediaRepo.save(updatedMedia);
}

Related

how to save entire conversation from bot into stoarge?

I have made a bot in v4 framework using c#. I want to save the entire conversation into a storage , in a readable format . Our requirement is to save the bot conversation in a readable format or plain text. In my case only user info is getting saved not the conversation between user and the bot.
You can use a middleware for that: TranscriptLoggerMiddleware
More info on middlewares
The middleware will handle saving transcript for you in a storage.
you can use below code
I have worked on nodejs but it should be similar to C#.
For each step call the logActivity
const { preserveService } = require('../../../Service/dbService');
await preserveService.logActivity(step.context, userData,Any param);
logActivity : async function (turnContext, userData,Any param){
try{
let userInfo = await userDataUtil.getUserInfo(turnContext,userData);
colNameAndValueArray = [
{
[PROPERTY_NAME.COLUMN_NAME] : 'response_from',
[PROPERTY_NAME.VALUE] : responsefrom,
[PROPERTY_NAME.DATATYPE] : DATATYPE.STRING
},
{
[PROPERTY_NAME.COLUMN_NAME] : 'user_session_id',
[PROPERTY_NAME.VALUE] : userInfo.userId,
[PROPERTY_NAME.DATATYPE] : DATATYPE.STRING
},
{
//conversation_id
[PROPERTY_NAME.COLUMN_NAME] : 'conversation_id',
[PROPERTY_NAME.VALUE] : turnContext._activity.conversation.id,
[PROPERTY_NAME.DATATYPE] : DATATYPE.STRING
},
{
[PROPERTY_NAME.COLUMN_NAME] : 'is_answered',
[PROPERTY_NAME.VALUE] : isAnswered,
[PROPERTY_NAME.DATATYPE] : DATATYPE.BOOLEAN
}
]
await this.insert(CONFIG.DB.AUDIT_TABLE, colNameAndValueArray);
}catch(err){
console.log(`------------------------`);
console.log(`Error occurred while inserting audit logs`);
console.log(err);
console.log(`------------------------`);
}}
insert : async function(tableName, colNameAndValueArray, returnColumnName){
let query = null;
try{
if(util.isNotEmptyString(tableName) && util.isNotEmptyArray(colNameAndValueArray)){
let columnNames = dbUtil.getColNames(colNameAndValueArray);
let columnValues = dbUtil.getColValues(colNameAndValueArray);
if(columnNames == null || columnValues == null){
throw new Error('Invalid column name or value. Kindly check the value you have passed');
}
query = `INSERT INTO ${tableName} (${columnNames}) VALUES (${columnValues}) ${util.isNotEmptyString(returnColumnName)? ` RETURNING ${returnColumnName}`: ''}`;
console.log(`------------------------`);
console.log(`Query : ${query}`);
console.log(`------------------------`);
return this.executeQuery(query);
}else{
return Promise.reject(REQUIRED_PARAMETER_MISSING);
}
}catch(err){
console.log(`------------------------`);
console.log(`Error occurred while executing insert query : ${ query != null ? query : '' }`);
console.log(err);
console.log(`------------------------`);
return Promise.reject(err);
}}
Hope this helps
Sanjeev Guatam

Abstract object not mapped correctly in Elasticsearch using Nest 7.0.0-alpha1

I am using NEST (.NET 4.8) to import my data, and I have a problem getting the mapping to work in NEST 7.0.0-alpha1.
I have the following class structure:
class LinkActor
{
public Actor Actor { get; set; }
}
abstract class Actor
{
public string Description { get; set; }
}
class Person : Actor
{
public string Name { get; set; }
}
I connect to Elasticsearch this way:
var connectionSettings = new ConnectionSettings(new Uri(connection));
connectionSettings.DefaultIndex(indexName);
var client = new ElasticClient(connectionSettings);
The actual data looks like this:
var personActor = new Person
{
Description = "Description",
Name = "Name"
};
var linkActor = new LinkActor
{
Actor = personActor
};
And the data is indexed like this:
result = client.IndexDocument(linkActor);
Using NEST 6.6 I am getting the following data in Elasticsearch 6.5.2:
"actor": {
"name": "Name",
"description": "Description"
}
However when using NEST 7.0.0-alpha1 I get the following data in Elasticsearch 7.0.0:
"actor": {
"description": "Description"
}
So the data from the concrete class is missing. I am obviously missing / not understanding some new mapping feature, but my attempts with AutoMap has failed:
client.Map<(attempt with each of the above classes)>(m => m.AutoMap());
Is is still possible to map the data from the concrete class in NEST 7.0.0-alpha1?
I found a workaround using the NEST.JsonNetSerializer (remember to install this), which allows me to pass a JObject directly:
Connect to Elasticsearch using a pool so you can add the JsonNetSerializer.Default:
var pool = new SingleNodeConnectionPool(new Uri(connection));
var connectionSettings = new ConnectionSettings(pool, JsonNetSerializer.Default);
connectionSettings.DefaultIndex(indexName);
var client = new ElasticClient(connectionSettings);
Convert the linkActor object from above to a JObject (JsonSerializerSettings omitted for clarity, add them to get CamelCasing):
var linkActorSerialized = JsonConvert.SerializeObject(linkActor);
var linkActorJObject = JObject.Parse(linkActorSerialized);
result = client.IndexDocument(linkActorJObject);
This gives the desired result:
"actor": {
"name": "Name",
"description": "Description"
}
It is a workaround, hopefully someone will be able to explain the mapping in the question.

Spring boot custom query MongoDB

I have this MongoDb query:
db.getCollection('user').find({
$and : [
{"status" : "ACTIVE"},
{"last_modified" : { $lt: new Date(), $gte: new Date(new Date().setDate(new Date().getDate()-1))}},
{"$expr": { "$ne": ["$last_modified", "$time_created"] }}
]
})
It works in Robo3T, but when I put this in spring boot as custom query, it throws error on project start.
#Query("{ $and : [ {'status' : 'ACTIVE'}, {'last_modified' : { $lt: new Date(), $gte: new Date(new Date().setDate(new Date().getDate()-1))}}, {'$expr': { '$ne': ['$last_modified', '$time_created']}}]}")
public List<User> findModifiedUsers();
I tried to make query with Criteria in spring:
Query query = new Query();
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("status").is(UserStatus.ACTIVE), Criteria.where("last_modified").lt(new Date()).gt(lastDay), Criteria.where("time_created").ne("last_modified"));
but it doesn't work, it returns me all users like there is no this last criteria not equal last_modified and time_created.
Does anyone know what could be problem?
I think that this feature is not supported yet by Criteria - check this https://jira.spring.io/browse/DATAMONGO-1845 .
One workaround is to pass raw query via mongoTemplate like this:
BasicDBList expr = new BasicDBList();
expr.addAll(Arrays.asList("$last_modified","$time_created"));
BasicDBList and = new BasicDBList();
and.add(new BasicDBObject("status","ACTIVE"));
and.add(new BasicDBObject("last_modified",new BasicDBObject("$lt",new Date()).append("$gte",lastDate)));
and.add(new BasicDBObject("$expr",new BasicDBObject("$ne",expr)));
Document document = new Document("$and",and);
FindIterable<Document> result = mongoTemplate.getCollection("Users").find(document);

MongoDB how update element in array using Spring Query Update

In my project I'm using SpringBoot 1.3.2 and org.springframework.data.mongodb.core.query.*
I'm trying to update element in array, in my main object i have array looking like this:
"sections" : [
{
"sectionId" : "56cc3c908f5e6c56e677bd2e",
"name" : "Wellcome"
},
{
"sectionId" : "56cc3cd28f5e6c56e677bd2f",
"name" : "Hello my friends"
}
]
Using Spring I want to update name of record with sectionId 56cc3c908f5e6c56e677bd2e
I was trying to to this like that but it didn't work
Query query = Query.query(Criteria
.where("sections")
.elemMatch(
Criteria.where("sectionId").is(editedSection.getId())
)
);
Update update = new Update().set("sections", new BasicDBObject("sectionId", "56cc3c908f5e6c56e677bd2e").append("name","Hi there"));
mongoTemplate.updateMulti(query, update, Offer.class);
It create something like:
"sections" : {
"sectionId" : "56cc3c908f5e6c56e677bd2e",
"name" : "Hi there"
}
But this above is object { } I want an array [ ], and I don't want it remove other elements.
Can any body help me how to update name of record with sectionId 56cc3c908f5e6c56e677bd2e using Spring
You essentially want to replicate this mongo shell update operation:
db.collection.update(
{ "sections.sectionId": "56cc3c908f5e6c56e677bd2e" },
{
"$set": { "sections.$.name": "Hi there" }
},
{ "multi": true }
)
The equivalent Spring Data MongoDB code follows:
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query;
import static org.springframework.data.mongodb.core.query.Update;
...
WriteResult wr = mongoTemplate.updateMulti(
new Query(where("sections.sectionId").is("56cc3c908f5e6c56e677bd2e")),
new Update().set("sections.$.name", "Hi there"),
Collection.class
);
Can use BulkOperations approach to update list or array of document objects
BulkOperations bulkOps = mongoTemplate.bulkOps(BulkMode.UNORDERED, Person.class);
for(Person person : personList) {
Query query = new Query().addCriteria(new Criteria("id").is(person.getId()));
Update update = new Update().set("address", person.setAddress("new Address"));
bulkOps.updateOne(query, update);
}
BulkWriteResult results = bulkOps.execute();
Thats my solution for this problem:
public Mono<ProjectChild> UpdateCritTemplChild(
String id, String idch, String ownername) {
Query query = new Query();
query.addCriteria(Criteria.where("_id")
.is(id)); // find the parent
query.addCriteria(Criteria.where("tasks._id")
.is(idch)); // find the child which will be changed
Update update = new Update();
update.set("tasks.$.ownername", ownername); // change the field inside the child that must be updated
return template
// findAndModify:
// Find/modify/get the "new object" from a single operation.
.findAndModify(
query, update,
new FindAndModifyOptions().returnNew(true), ProjectChild.class
)
;
}

Elasticsearch: bulk update multiple documents saved in a Java String?

I can create the following string saved in a Java String object called updates.
{ "update":{ "_index":"myindex", "_type":"order", "_id":"1"} }
{ "doc":{"field1" : "aaa", "field2" : "value2" }}
{ "update":{ "_index":"myindex", "_type":"order", "_id":"2"} }
{ "doc":{"field1" : "bbb", "field2" : "value2" }}
{ "update":{ "_index":"myindex", "_type":"order", "_id":"3"} }
{ "doc":{"field1" : "ccc", "field2" : "value2" }}
Now I want to do bullk update within a Java program:
Client client = getClient(); //TransportClient
BulkRequestBuilder bulkRequest = client.prepareBulk();
//?? how to attach updates variable to bulkRequest?
BulkResponse bulkResponse = bulkRequest.execute().actionGet();
I am unable to find a way to attach the above updates variable to bulkRequest before execute.
I notice that I am able to add UpdateRequest object to bulkRequest, but it seems to add only one document one time. As indicated above, I have multiple to-be-updated document in one string.
Can someone enlighten me on this? I have a gut feel that I may do things wrong way.
Thanks and regards.
The following code should work fine for you.
For each document updation , you need to create a separate update request as below and keep on adding it to the bulk requests.
Once the bulk requests is ready , execute a get on it.
JSONObject obj = new JSONObject();
obj.put("field1" , "value1");
obj.put("field2" , "value2");
UpdateRequest updateRequest = new UpdateRequest(index, indexType, id1).doc(obj.toString());
BulkRequestBuilder bulkRequest = client.prepareBulk();
bulkRequest.add(updateRequest);
obj = new JSONObject();
obj.put("fieldX" , "value1");
obj.put("fieldY" , "value2");
updateRequest = new UpdateRequest(index, indexType, id2).doc(obj.toString());
bulkRequest = client.prepareBulk();
bulkRequest.add(updateRequest);
bulkRequest.execute().actionGet();
I ran into the same problem where only 1 document get updated in my program. Then I found the following way which worked perfectly fine. This uses spring java client. I have also listed the the dependencies I used in the code.
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
private UpdateQuery updateExistingDocument(String Id) {
// Add updatedDateTime, CreatedDateTime, CreateBy, UpdatedBy field in existing documents in Elastic Search Engine
UpdateRequest updateRequest = new UpdateRequest().doc("UpdatedDateTime", new Date(), "CreatedDateTime", new Date(), "CreatedBy", "admin", "UpdatedBy", "admin");
// Create updateQuery
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(Id).withClass(ElasticSearchDocument.class).build();
updateQuery.setUpdateRequest(updateRequest);
// Execute update
elasticsearchTemplate.update(updateQuery);
}

Resources