Facing an issue while rollback saving data.
Problem:
In my java method there are three saving actions. Data save to different table. I want when a saving fails then all saved transaction will be rollback.
Example, there are three tables consist of master table and sub table. All table save in a method. APVoucherEntryDetails is the child table, when it saves fail then upper transactions should be rollback.
How can I do it ?
Thanks in advance
#Override
public ApiResponse saveVoucher(APVoucherBatch batch) {
APVoucherBatch savedBatch = voucherBatchRepo.save(batch); //table 1
//==========save entry=============
List<APVoucherEntry> entryList = batch.getEntryList();
for(APVoucherEntry info: entryList){
info.setVoucherBatch(savedBatch);
info.setBatchNo(savedBatch.getBatchNo());
APVoucherEntry savedEntry = entryRepo.save(info); //table 2
//==========save detail=============
List<APVoucherEntryDetails> detailsList = info.getDetailsList();
for(APVoucherEntryDetails dtl: detailsList){
dtl.setBatchList(savedBatch);
dtl.setEntryInfo(savedEntry);
detailsRepo.save(dtl); //table 3
}
}
return new ApiResponse();
}
Related
I have three SQL tables
The "Accedant" table that has an idAccedant
The "Emetteur" table that has an idEmetteur and a foreign key towards the Accedant table
The "Asso_Etab_Emet" table which is an assocation table between a table called "Etablissement" and the "Emetteur" table.
So the "Asso_Etab_Emet" table has two foreign keys, one towards the Etablissement table and one toward the Emetteur table
I want to build a
Specification<Etablissement>
with the idAccedant as input data, to get, at the end, the list of all the Etablissement linked to an Emetteur :
Page<Etablissement> etablissementsPage = etablissementDao.findAll(specEtab, configPage);
My code that aims at building the Specification is the following
#Override
public Specification<Etablissement> findActifByExploitantSpec(Long idAccedant) {
return ((root, query, builder) -> {
Subquery<Emetteur> emetteurSubquery = query.subquery(Emetteur.class);
Root<Emetteur> emetteurRoot = emetteurSubquery.from(Emetteur.class);
emetteurSubquery
= emetteurSubquery.where(builder.equal(emetteurRoot.get(Emetteur_.accedant).get(Accedant_.id), idAccedant));
Subquery<Etablissement> etablissementSubquery = query.subquery(Etablissement.class);
Root<Etablissement> etablissementRoot = etablissementSubquery.from(Etablissement.class);
Root<EtablissementEmetteur> etablissementEmetteurRoot = etablissementSubquery.from(EtablissementEmetteur.class);
etablissementSubquery
= etablissementSubquery.select(etablissementEmetteurRoot.get(EtablissementEmetteur_.etablissement));
etablissementSubquery = etablissementSubquery.where(
builder.in(etablissementEmetteurRoot.get(EtablissementEmetteur_.emetteur)).value(emetteurSubquery));
return builder.in(root).value(etablissementSubquery);
});
}
I have a
"No explicit selection and an implicit one could not be determined" error
when testing via my Angular webapp
Is it possible to delete all rows from a table and then update the table in a single transaction? I found this documentation: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-example.html
I tried implementing it for a single item:
productItemKey.put("test_id", new AttributeValue(String.valueOf(150)));
machine_ids.add(0, String.valueOf(newAssignments.get(150).get(0).getID()));
machine_ids.add(1, String.valueOf(newAssignments.get(150).get(1).getID()));
machine_ids.add(2, String.valueOf(newAssignments.get(150).get(2).getID()));
Map<String, AttributeValue> expressionAttributeValues = new HashMap<String, AttributeValue>();
expressionAttributeValues.clear();
expressionAttributeValues.put("test_id", new AttributeValue(String.valueOf(150)));
expressionAttributeValues.put("assignments", new AttributeValue().withSS(machine_ids));
expressionAttributeValues.put("needsMoreMachines", new AttributeValue().withBOOL(output.doesCTneedMoreMachines(150)));
Delete deleteItems = new Delete()
.withTableName("test_table")
.withKey(productItemKey);
Put markItemSold = new Put()
.withTableName("test_table")
.withItem(expressionAttributeValues);
Collection<TransactWriteItem> actions = Arrays.asList(
new TransactWriteItem().withDelete(deleteItems),
new TransactWriteItem().withPut(markItemSold));
TransactWriteItemsRequest placeOrderTransaction = new TransactWriteItemsRequest()
.withTransactItems(actions);
try {
client.transactWriteItems(placeOrderTransaction);
System.out.println("Transaction Successful");
...
But i keep getting this error:
Transaction request cannot include multiple operations on one item
You can manipulate up to 100 (separate) items in a transaction. You could only delete all rows if you have fewer than 100 rows.
The best way to bulk delete all rows is to delete the table. You cannot do that transactionally with the creation of the table again. Better to make a new table with a new name and then delete the old.
If you explained what your fundamental goals are we could give some advice.
I have created a SpringBoot app that connects to two databases (using separate JPA config) for data read and write operations. Data is manipulated and partially persisted in two databases (DB servers are in two separate infrastructures). Similarly, the data from these separate DBs are combined and served back to the client during the read operations. Both read and write operations for a single record took more than 3 sec each (I think it's obvious as the DBs are in separate infra).
I need to improve the performance of both read and write operations. I have improved the read performance to less than a sec by introducing the Redis cache. How can I improve the performance of write operations? Please suggest possible options. Thanks in advance!
Code: [Here customerRepository refers to one DB and splitCustomerRepository refers to the other. First save the partial data in first DB and use the primary key id to create the remaining data in second DB]
public String createCustomer(CustomerRequest customerRequest) {
String message = "";
try {
customerRequest = applyRules(customerRequest);
CreditCardRequest cardRequest = customerRequest.getCreditCard();
CreditCard card = CreditCard.builder().cardNumberPart1(cardRequest.getCardNumberPart1())
.cardType(cardRequest.getCardType()).cvv(cardRequest.getCvv()).expiry(cardRequest.getExpiry())
.pinPart1(cardRequest.getPinPart1()).build();
Customer customer = Customer.builder().address(customerRequest.getAddress()).age(customerRequest.getAge())
.name(customerRequest.getName()).ssnPart1(customerRequest.getSsnPart1()).creditCard(card).build();
for (Address address : customerRequest.getAddress()) {
address.setCustomer(customer);
}
customer = customerRepository.save(customer);
addressRepository.saveAll(customerRequest.getAddress());
SplitCreditCard splitCreditCard = SplitCreditCard.builder().id(customer.getCreditCard().getId())
.cardNumberPart2(cardRequest.getCardNumberPart2()).pinPart2(cardRequest.getPinPart2()).build();
SplitCustomer splitCustomer = SplitCustomer.builder().id(customer.getId()).creditCard(splitCreditCard)
.ssnPart2(customerRequest.getSsnPart2()).build();
splitCustomerRepository.save(splitCustomer);
message = "Customer successfully created!";
} catch (Exception e) {
LOGGER.error("Exception occurred while creating customer", e);
message = "Failed to create customer, exception occurred - " + e.getMessage();
}
return message;
}
In my table I render rows contains components. After loading data source to table sometimes there are empty fields (components aren't visible, text - yes). I have not any exceptions.
This happens when I scrolling table content. After refreshing table data source everything is ok.
What's wrong?
In attachement there is an example.
I found solution. I think so that might be an bug.
INVALID SOLUTION:
Load data to table
Scroll table with data to eg. 50% of table content
Load new data to table
Table doesn't display all components
CORRECT SOLUTION:
Load data to table
Scroll table with data to eg. 50% of table content
Scroll table to top, to the first table item
Load new data to table
Table display all components
In Vaadin 7.4.1 there is that same bug. Maybe recreating table should help?
OK. Now it works. This is temporary solution. I re-create table and load data to new table:
private void createTable() {
pzbs = (FilterTable) buildTable();
h.addComponent(pzbs);
h.setExpandRatio(pzbs, 1.0f);
}
private void recreateTable() {
h.removeComponent(pzbs);
createTable();
}
private Component buildRoutes() {
routes = new ListSelect() {
{
setNullSelectionAllowed(false);
setSizeUndefined();
setWidth(100.0f, Sizeable.Unit.PERCENTAGE);
setHeight(100.0f, Sizeable.Unit.PERCENTAGE);
setImmediate(true);
}
};
routes.addValueChangeListener((Property.ValueChangeEvent event) -> {
if (routes.getValue() != null) {
recreateTable();
countAndUpdatePercentage(countCorrectReadouts());
sendedToPSG.select(null);
selectedRoute = (KTREntity) routes.getValue();
updateTable();
}
});
return routes;
}
How do I delete more than one record at a time in salesforce?
Delete all Salesforce Account objects (up to the artificially imposed limitations per SF query on whatever the object happens to be):
delete new List<Account>([select Id from Account]);
Where "Account" is any Salesforce object (or custom object you've created). You can fine-tune the delete by adding the "WHERE" clause:
delete new List<Account>([select Id from Account where ... ])
Or the "LIKE" clause:
delete new List<Account>([select Id from Account where LastName like 'Jon%']);
Is this what you want?
Salesforce CRM -delete()
Here is a method in Java that would delete one row in salesforce.
Salesforce ID's are 18 character case sensitive keys. Every table has an id that is unique across the entire database. So you can delete by an id, and salesforce will know what table you are referring to.
public static boolean salesforceDevDeleteById(String id){
SalesforceConnector sf;
boolean deletesuccess = false;
try{
sf = new SalesforceConnector();
sf.login("youruser#yourhost.com",
"keyasdf", "keyasdf", "dev");
if (!id.equals("")){
DeleteResult[] deleteResults = sf.delete(new String[]{id});
for(DeleteResult r : deleteResults){
deletesuccess = r.isSuccess();
break;
}
}
else{
System.out.println("Failed to delete");
}
System.out.println("delete success: " + deletesuccess);
}
catch(Exception e){
e.printStackTrace();
System.out.println("error");
}
return deletesuccess;
}
Notice where it invokes the delete method. You can load a set of id's there.
psuedo:
List _list = new List();
_list.add(a);
_list.add(b);
delete(_list);