So, new question. I have an object with several objects. This is object is an array with several instances and it is specific to the current user. In other words, I will go and initiate the object the first time I use the app, everytime I use the app I will be adding items to the object each of them with a unique ID. This ID should be incremental, so I’m trying to write the code so that when I map my input from my form, I will add to the last ID. Example:
First time I use the app I make 3 objects therefore the objectId is 3. The next time I open the app and run it I want the objectId to start at four. This is the code I’m using:
//Creating a list filled with object
List objectInstance = objectDAO.find(0,10000);
//Defining the last item in the BDO
int lastObjectNum = currentObject.size();
//objectId is a string so transforming last item number into string to query value
String lastObject = Integer.toString(lastObjectNum)
//Retreiving objectId actual value for objectId in BDO
String lastObjectId = objectDAO.findByObjectId(lastObject,0,10000).objectId;
//Parsing string to get actual integer value to add new ID numbers
int numId = Integer.parseInt(lastObjectId.trim());
//Initialize value that will define objectId of new items
int i = 0;
//Verify if there are older items in the collection
if (numId==0 || numId<1){
//If empty collection initial value is one
i = 1;
}
else {
//Else if collection is not empty it takes the value of the last item
i = numId;
}
//Setting object Id
object.setObjectId(""+i);
With this code I’m getting an error: java.lang.NumberFormatException: For input string: “”
I create a diagram that I think demonstrate how to achieve what you are looking for.
I define an Invoice business data with two attributes:
creator (Long): the id of the Bonita BPM user who create the invoice
id (Long): invoice id that is unique for a given user (multiple users will have invoice with same id)
An additional attribute is automatically added by Bonita Business Data Model:
persistenceId (Long): this attribute is automatically incremented for each Invoice created (unique for all invoices)
The process definition have a reference to the newly created invoice. I use a groovy script to create the Invoice object in the default value of the reference.
I use Bonita BPM Engine API to find the id of the user who create the process instance and store this information in creator attribute of the Invoice object.
To generate a unique id per user for the invoice I use a Business Data Model custom query that search for the current user maximum invoice id value:
SELECT COALESCE(MAX(i.id), 0)
FROM Invoice i
WHERE i.creator = :creator
COALESCE function is the solution to return 0 by default in case of no invoice already exist.
Search query require one input: creator id
In order to make sure that this remain efficient I define an index on creator and invoice id.
The search query is called from the Groovy script using the variable invoiceDAO available from Groovy editor drop down list “Select a provided variable…”
On the first step form I display all (actually limited to 100) created invoices.
If you run the process from the Studio (deploy and create one instance) and then use “Processes” menu to start multiple instances with various users (e.g. helen.kelly with password bpm) you will see that id per user is actually incremented individually.
So this seems to be working and it turned out to be a lot simpler for this specific case. It helped to recognize that the number would equal the number of instances in the array plus one. So I wouldn’t actually have to read the value for the ID, this means I could even make it a more complex string ID!
Anyway, thanks for all your help! Let me know if you see any potential errors or better ways of writing this code!
String currentUser = "";
currentUser = BonitaUsers.getProcessInstanceInitiator(apiAccessor,processInstanceId).userName;
List currentBDO = detailWeekObjsDAO.findByWkObjUser(currentUser,0,100);
int lastNum = currentBDO.size();
int i = 0;
if (lastNum ==0 || lastNum<1){
i = 1;
}
else {
i = lastNum+1;
}
Thank you for your patience Antoine. The entire process is some what larger so sharing it may not be the most effective way. I will try to pose an analogous example.
The organization has x number of sales people. The process is made for each of them to create invoices. Rather than creating an instance of the object per each user, it is setup that all invoices are created in the same object simply distinguished by the user name on each instance. Each invoice also has an Id attribute which is sequential and unique to each user. So for example:
The InvoiceNumber could be linked to the PersistenceID, but I would like the InvoiceID to be incremental according to each user. So if Antoine, opens the process again, the new instance of the invoice would create an InvoiceID 0003. Due to the analysis I hope to do afterwards I want this distinction and for ALL the invoices to be in the same database.
So from the process stand point, I want the Groovy script to go into the saved database, query the search by current user and then find the last InvoiceID and increment from that point. If the user has not created an invoice, the InvoiceID starts from 0001.
I hope this makes more sense. Thank you for your time!
my advice. Change the design. It will not work like this for long and will be a real PITA to modify later.
I remember working on something like this about 20 years ago completely unrelated to Bonitasoft, in COBOL if I remember rightly.
The easiest solution without too much effort would be to change the InvoiceID to something else like a Datetime field. It will always in in sequence for the salesman in question and no need to “work out the number”.
Otherwise I would do what nearly everyone else does:
BDM for Invoices
BDM for Sales person
Create a relationship between them
Years of other peoples knowledge has gone into this structure, why change it?
Seán, thank you for your comment. The invoiceId is just an example, I’m sure there are other cases where you may want to add onto a number that you have already stored in a BDO. I will try Antoine’s solution and see how it works out for me. All in all, beyond the specific functionality of my current application, I thought it’s an interesting problem to solve.
Bonitasoft empowers development teams with Bonita, the open-source and extensible platform to solve the most demanding process automation use cases. The Bonita platform accelerates delivery of complex applications with clear separation between capabilities for visual programming and for coding. Bonita integrates with existing solutions, orchestrates heterogeneous systems, and provides deep visibility into processes across the organization.