I was trying to update a row on the database and noticed that once the row was updated, getAll stopped working correctly. All the records that were updated, started missing from getAll's result.
for instance, imagine you have a list of products [product1, product2, product3]. if I do something like product2.someProperty = 2 followed by a product2.merge(), product two will start missing from the list. So the result of Products.getAll() will be [product1, product3].
(Sorry if this is a noob question)
If I perform a Product.get(idOfUpdatedProduct), it will work.
I've checked the database and the merge is updating the data correctly.
The problem seems to be on the GetAll() method.
findAll() presents the same behavior.
my code:
---action
def update() {
Product product = productService.detail(params.id?.toLong())
bindData(product, params)
productService.updateProduct(product)
redirect action: "show", params: [id: params.id]
}
---service
void updateProduct(product) {
product.validate()
StringBuilder str = new StringBuilder()
product.errors.allErrors.each { str << "${it}" }
if (!str.toString().isEmpty()) throw new Exception("Error: ${str.toString()}")
product.merge(flush: true, failOnError: true)
}
I found the problem.
the result was actually being returned, but for some reason, it was placed in the middle of the list.
I solved it by sorting the list.
Related
I am working on a solution where I am using vertx 3.8.4 and vertx-mysql-client 3.9.0 for asynchronous database calls.
Here is the scenario that I have been trying to resolve, in a proper reactive manner.
I have some mastertable records which are in inactive state.
I run a query and get the list of records from the database.
This I did like this :
Future<List<Master>> locationMasters = getInactiveMasterTableRecords ();
locationMasters.onSuccess (locationMasterList -> {
if (locationMasterList.size () > 0) {
uploadTargetingDataForAllInactiveLocations(vertx, amazonS3Utility,
locationMasterList);
}
});
Now in uploadTargetingDataForAllInactiveLocations method, i have a list of items.
What I have to do is, I need to iterate over this list, for each item, I need to download a file from aws, parse the file and insert those data to db.
I understand the way to do it using CompositeFuture.
Can someone from vertx dev community help me with this or with some documentation available ?
I did not find good contents on this by googling.
I'm answering this as I was searching for something similar and I ended up spending some time before finding an answer and hopefully this might be useful to someone else in future.
I believe you want to use CompositeFuture in vertx only if you want to synchronize multiple actions. That means that you either want an action to execute in the case that either all your other actions on which your composite future is built upon succeed or at least one of the action on which your composite future is built upon succeed.
In the first case I would use CompositeFuture.all(List<Future> futures) and in the second case I would use CompositeFuture.any(List<Future> futures).
As per your question, below is a sample code where a list of item, for each item we run an asynchronous operation (namely downloadAnProcessFile()) which returns a Future and we want to execute an action doAction() in the case that all the async actions succeeded:
List<Future> futures = new ArrayList<>();
locationMasterList.forEach(elem -> {
Promise<Void> promise = Promise.promise();
futures.add(promise.future());
Future<Boolean> processStatus = downloadAndProcessFile(); // doesn't need to be boolean
processStatus.onComplete(asyncProcessStatus -> {
if (asyncProcessStatus.succeeded()){
// eventually do stuff with the result
promise.complete();
} else {
promise.fail("Error while processing file whatever");
}
});
});
CompositeFuture.all(futures).onComplete(compositeAsync -> {
if (compositeAsync.succeeded()){
doAction(); // <-- here do what you want to do when all future complete
} else {
// at least 1 future failed
}
});
This solution is probably not perfect and I suppose can be improved but this is what I found works for me. Hopefully will work for someone else.
Start to try out the Apache Beam and try to use it to read and count HBase table. When try to read the table without the Count.globally, it can read the row, but when try to count number of rows, the process hung and never exit.
Here is the very simple code:
Pipeline p = Pipeline.create(options);
p.apply("read", HBaseIO.read().withConfiguration(configuration).withTableId(HBASE_TABLE))
.apply(ParDo.of(new DoFn<Result, String>() {
#ProcessElement
public void processElement(ProcessContext c) {
Result result = c.element();
String rowkey = Bytes.toString(result.getRow());
System.out.println("row key: " + rowkey);
c.output(rowkey);
}
}))
.apply(Count.<String>globally())
.apply("FormatResults", MapElements.via(new SimpleFunction<Long, String>() {
public String apply(Long element) {
System.out.println("result: " + element.toString());
return element.toString();
}
}));
when use Count.globally, the process never finish. When comment it out, the process print all the rows.
Anyy ideas?
Which version of beam are you using?
Thanks for bringing this issue. I tried to reproduce your case and indeed there seems to be an issue with colliding versions of guava that breaks transforms with HBaseIO. I sent a pull request to fix the shading of this, I will keep you updated once it is merged so you can test if it works.
Thanks again.
Entity Framework: 6.1.3.
I have a function that reads a simple table for a record and either updates it or first creates a new entity. Either way it then calls AddOrUpdate and SaveChangesAsync. This function has worked for quite some time without any apparent problem.
In my current situation, however, I'm getting a return value of 0 from SaveChangesAsync. I have a break point just before the save and verified that the record doesn't exist. I step through the code and, as expected, a new entity was created. The curious part is that the record is now in the table as desired. If I understand the documentation, 0 should indicate that nothing was written out.
I'm not using transactions for this operation. Other database operations including writes would have already occurred on the context prior to this function being called, however, they should all have been committed.
So how can I get a return of 0 and still have something written out?
Here is a slightly reduced code fragment:
var settings = OrganizationDb.Settings;
var setting = await settings.FirstOrDefaultAsync(x => x.KeyName == key).ConfigureAwait(false);
if (setting == null)
{
setting = new Setting()
{
KeyName = key,
};
}
setting.Value = value;
settings.AddOrUpdate(setting);
if (await OrganizationDb.SaveChangesAsync().ConfigureAwait(false) == 0)
{
//// error handling - record not written out.
}
i m having a very weird issue, i m using grails afterUpdate in domain for saving the activity on db.
The code i m using to create a record in my collection "DatabaseEvent" is working in controller and saving the object perfectly but the same code is not saving object in afterUpdate() method ,
even the code is executing and not giving any error but still it is not saving the object
def afterUpdate () {
println "==++++==="
def dbEvent = new DatabaseEvent(type: "Created", entityClass : "Central Zone", objectId: this.id )
if(!dbEvent.save()){
println "======"
dbEvent.errors.each{
println it
}
}
else{
println "saved=="
}
}
it does print out "==++++===" and goes in else and print saved==
but the object is not saved in db, i m using mongodb
and sometimes it gives , the stackoverflow error and creates a lot of entries in just one call, i dont understand it, any solution for this ??
i have edited the question, as one i thing i noticed it is giving me stackoverflow when i use save(flush :true) and created a lots of records in one call and if i dont use it , it just dont create any ??
Transaction in service layer is coupled with the datasource associated, here you need to initiate a transaction to save the data like this
def afterUpdate () {
println "==++++==="
DatabaseEvent.withTransaction { status->
def dbEvent = new DatabaseEvent(type: "Created", entityClass : "Central Zone", objectId: this.id )
if(!dbEvent.save()){
println "======"
dbEvent.errors.each{
println it
}
}
else{
println "saved=="
}
}
}
I'm doing a "Preview" action so that you can preview your changes on edits before doing them. Effectively what I'm doing is calling the update function (not action) without saving.
Update function code-bits:
// Updates existing schedules to new values; Working
UpdateSchedules(...);
// Removes existing schedules no longer in date-range; Not working
RemoveSchedules(...);
{
...
foreach(schedule in schedulesToRemove) { db.Entry(schedule).State = EntityState.Deleted; }
db.Schedules.RemoveRange(...);
...
}
// Adds schedules new to date-range; Working
AddSchedules(...);
{
...
db.Schedules.Add(...);
...
}
Retrieval Code:
// The results have the modified and added entities, but they also have the removed entities.
viewModel.Results = db.PaymentRecurringSchedules.Where(s => s.PaymentSetupHeaderID == headerID).OrderBy(s => s.PaymentDate).ToList();
My intention with this code is to not call db.SaveChanges() since it's just a preview, but I still want only the schedules that weren't removed (saved or unsaved).
What I've tried
I tried changing the state of the removed items as you can see above.
I tried doing a .Where(s => db.Entry(s).State != EntityState.Deleted) it didn't like that at all (i.e. execution errors).
How can I get the results where the items I removed but are unsaved will still be filtered out of the results list?
Version: 6.0 (In case it matters)
Don't have VS at hand, but i think that this should work as you requested:
List<Object> deletedEntities = context.ChangeTracker.Entries()
.Where(x => x.State == System.Data.EntityState.Deleted)
.Select(x => x.Entity)
.ToList();
Take care that you may want to filter also to specific Entity type/s.