I am doing a barcode scan application, so every time user scan a barcode the application retrieve a row from database and fill to the DataTable. I set clearbeforefill=false because i want the user to see the result for every scan. I want to prevent duplicate scan of one barcode when user scan too fast.
I found that if I set DataSet.EnforceConstraint to true, it will prompt a unique violation message. However i just want the application to bypass the scan silently.So I tried to catch the ConstraintException as below
try{
tableadapter.fill(datatable,barcode);
}
catch(ConstraintException ex){
}
If i do nothing in the catch block, the DataTable will allow duplicated row, so do i need to manually remove duplicated item or check everytime before i fill a DataTable? Thanks for help
Related
i am using Spring/Hibernate/ZK. In one tab i get object from DB for editing by user, but second user can open the same tab and the same object for editing . I want to informed second user whit message like "This object is аlready open" and hide buttons for save.Тhus second user can see current data from DB to this object but can`t edint him.Is there a way to check session for this object or another way to do that.
The other answers mostly look at the database, but if all users use the same zk application to access the database, you could keep track of opened objects in the Composer or ViewModel (depending whether you use MVC or MVVM; I'll just call it controller).
Your controller would need a static list of objects that are currently modified. If a user requests to open an object that is not in the list, everything is fine and your controller enables the fields and save button. Otherwise, those are disabled and/or you display a message.
The tricky part is clearing objects from that list. If a user presses the save button, you just remove the object from the list. But what if the user doesn't and just closes the tab or their session just times out? In this case you need a callback, or a mechanism that regularly checks whether the screen is still open.
You could achieve this by adding a zk timer to the tab that pings every now and then and updates the timestamp in your static list (so make it a map). If a new user tries to edit the object, check how old the last timestamp is. If it is old enough (i.e. the previous user saved it or abandoned the screen), allow them to edit it.
Still, you have to think about what to do if a user just keeps the screen open. How long are they allowed to keep the lock on the object? This is an issue in Microsoft Office as well. If multiple users try to open an Excel file from a network location, the first one gets to lock and the others cannot save until that user saves.
You may have additional field which indicates that column is being edited. When first user starts work, the field would be updated. The second user would query object with 'on hold' status and your code would handle this.
Other way - use Hibernate #Version field in your entity. It holds object version which is incremented after every update operation. If second user would save object after first one already saved, it would throw OptimisticLockException which you could handle in your code. More about optimistic and pesimistic locking: Chapter 5. Locking. Related discussions: Hibernate Automatic Versioning and When to use #Version and #Audited in Hibernate?
The best solution is to use Optimistic Concurrency Control with Versioning and when Hibernate throws Concurrency Update issue due to same row is being updated in two transaction then use one of below strategy
First Wins Strategy
Last Wins Strategy
Merge Conflicting Update Strategy
First Wins Strategy is not good solution as it leads to lost update and user will get frustrated that all his work is lost.
By Last Wins Strategy one of user will get error message that you are working on Stale data and start your transaction again . By this way also user can get frustrated due to fact that now again he need to restart operation from beginning but his changes will not lost.
Instead go with Merge conflicting Update Strategy, when Hibernate throws Stale object exception reload screen with new data and user will see updated result and allow him to proceed with latest data. In this user changes will not loss and user will not get error message , just his screen reloads with fresh data and he can decide whether to proceed or not .
You can take example any e-commerce site and you will get one of result of either Last Wins Strategy or Merge Conflicting Update Strategy. Two user can start to by one item but one of user will get message in last screen that item is not stock.
In the salesInvoice ssrs Report i have added a table called carTableEquipTmp which is not there by default, which I insert into along with the other tables(SalesinvoiceTmp and SalesinvoiceHeaderFooterTmp) in SalesInvoiceDP.InsertIntoSalesInvoiceTmp().
Even though my table carTableEquipTmp is getting successfully inserted into, the data doesn't show up on the report if i print a proforma report.
If i add test values to the carTableEquipTmp table in SalesInvoiceDP.processReport() they show up on the proforma invoice, but there's no way for me to get any parameters needed to set in the correct data into the table at this point. If i stop at this point in the debugger none of the data is present because processreport() is being called from a lower level in the code.
I think it might be a problem with maybe pack/unpack or that the proforma code runs from a server instance as the code run when it is proforma is quite different.
I can see that SalesInvoiceJournalPostBase.CreateReportData() creates an instance of salesInvoiceDP
salesInvoiceDP = new SalesInvoiceDP();
salesInvoiceDP.parmDataContract(salesInvoiceContract);
salesInvoiceDP.parmUserConnection(new UserConnection(true));
salesInvoiceDP.createData();
And that this might have something to do with it... but i still cant get the data i want in the carTableEquipTmp table.
So any idea on how to make Ax 2012 accept this new table i have added as it gets inserted into just like the other tables and there seems to be no problem...
I hope you guys can help.
The SalesInvoice report has two data classes you need to look at for the data provider, SalesInvoiceDP and SalesInvoiceDPBase. SalesInvoiceDPBase extends SrsReportDataProviderPreProcess, so there are a couple extra steps you need to take in order to add new datasources to the report.
In the salesInvoiceDP class, there is a method called useExistingReportData(), which re-inserts the pro-forma temp table data under a user connection, so the SrsReportDataProviderPreProcess framework will pick it up in your report. When the pro-forma process creates the report data, it doesn't insert with a user connection so it doesn't get added to the report. This method only gets called when the report is being run pro-forma.
You will need to add your temp table to this method, and follow the pattern for the other tables, so your code will look something like this:
//this is different from the buffer you insert your data with
CarTableEquipTmp localCarTableEquipTmp;
...
recordList = new RecordSortedList(tableNum(carTableEquipTmp));
recordList.sortOrder(fieldNum(carTableEquipTmp, RecId));
//You will need to add a field to relate your temp table
//to the current invoice journal, and insert it in
//InsertIntoSalesInvoiceTmp() if thats where you're inserting your table.
while select localCarTableEquipTmp
where localCarTableEquipTmp.JournalRecId == jourRecId
{
recordList.ins(localCarTableEquipTmp);
}
delete_from localCarTableEquipTmp
where localCarTableEquipTmp.JournalRecId == jourRecId;
recordList.insertDatabase(this.parmUserConnection());
This method re-inserts your data under the framework and deletes the original data. The data that was re-inserted will then get picked up by the framework and show in your report. If you open CarTableEquipTmp in the table browser, you will most likely see data still there from all the times you have tried running the report. This is why we have the delete_from operation after we re-insert the data. When data is inserted under a userConnection, it is automatically deleted when the report is finished
The other method you will want to modify is SalesInvoiceDP.setTableConnections(), and you will just need to add the following line:
CarTableEquipTmp.setConnection(this.parmUserConnection());
This will set the user connection for your table when running regular (not pro-forma). You will probably want to delete the data that is stored currently in your temp table using alt+F9 from the table browser.
Other than that it's all standard RDP stuff, but it sounds like you have that part working fine. Your temp table must be of type "Regular" for this to work.
I'm writing a webmail-application by using smartgwt.
I'm trying to use auto-search on TextItem.
The TextItem is added a keyup-Handler and go to server side to do sql search every time when user
key-in a word. (I don't use js search because the speed of ie is very slow when doing filtering)
Further more, i use DSResponse.setData to create the listgrid records.
The problem is when setData is called, the grid always has a "loading data" message during the search.
How can i prevent this? Or just like PickListProperties, no "loading data" message, grid show the result without refresh.
Thanks!!
The message will appear whenever the grid calls the server to retrieve the data.
However you can, get the entire data on load, and whenever the the user keys in a word, just filter the grid by creating a new criteria like this :-
Criteria criteria=new Criteria();
criteria.addCriteria("name",textBox.getValue());
grid.filterData(criteria);
This way the loading message would not appear and also it would save you trips to server.
I am trying to implement the DOJO data gird in my application. On load of the xPages I am getting the current user id in a session scope variable and filtering the REST services that supplies the data grid the data from a view, based on the user id. I have used the "keys" property to filter the values so that the current user should be able to see the values only relevant to him in the grid. This is working fine, but when I try to sort the results once the page is loaded it starts displaying blank values and sort does not work. I have made sure that the columns I require to sort are also made sorted for the back-end view by checking the "Click on column header to sort" option in the view. Still I am unable to get the sorting working for columns. Please let me know if there is a work-around for this problem or am I doing or not doing something for the default sort not to work as expected.
Nash, I have had similar issues with the blank rows as you describe. I think the blanks lines are rows that don't match the keys. Here are my tips for fixing this. The issue I think is not with your grid but your Rest service.
Use a viewJsonService type of rest service
Use a category filter instead of keys
Make your category filter code similar to mine below. This will ensure that you don't show documents to someone who shouldn't see them. When the category is null, the Rest service will show all documents. This isn't causing the blank lines, but is a best practice IMO.
var category:String = lineItemBean.getThisUNID();
//wherever your category comes from, maybe session.getUserName() in your case
if(category == null){
return "show nothing"
} else {
return lineItemBean.getThisUNID();
}
I hope this helps. My guess is that this will fix your sorting issues as well.
I used the Data Source Configuration Wizard to create a connection to an Access database and fill a listbox. All is well except the list is not sorted. If I set the sort order via the properties dialog, then the list is sorted, but the associated textboxes that display information from the database are still sorting in the order that was defined in the dataset.
I know I need to sort the dataset, but since the Wizard created the connection, I don't know how to find the code. The only code I can find is in the form load section and it is as follows:
this.membership_LogTableAdapter.Fill(this.membership_Log_DataSet.Membership_Log);
I tried to manipulate the sort order by doing the following, but it did not work:
this.membership_Log_DataSet.DefaultViewManager.DataViewSettings["Membership_Log"].Sort = "Last_Name ASC";
Anyone have any ideas?
It looks like you're filling/binding-to individual datatable. If is the case, try setting sorting of that specific table:
this.membership_Log_DataSet.Membership_Log.DefaultView.Sort = "Last_Name ASC";
I figured it out. I double clicked the Membership_Log_DataSet.xsd file in the solution explorer and then I right clicked the Fill,GetData method and clicked properties and then I was able to alter the SQL command text by adding ORDER BY Last_Name to the auto-generated SQL code.