Hello everyone,
I’m working on a project where I have some basics functions in a groovy script from “Manage Groovy Scripts”.
My main issue is to get the DAO in my function to be able to acces my objects.
The first thing I tried was to send the DAO I need as parameters
For exemple :
public static Besoin updateDemandeContributionBesoin(Map<String, Serializable> besoinInput, BesoinDAO besoinDAO, RefProjectDAO refProjectDAO) {
But it’s look like there is a proper way to do it with the businessObjectDAOFactory. But for some reason it does not work and I haven’t seen anything in the documentation.
BusinessObjectDAOFactory businessObjectDAOFactory = new BusinessObjectDAOFactory(); String daoClassName = DemandeContributionDAO.class.name; DemandeContributionDAO currentDemandeContributionDAO = businessObjectDAOFactory.loadClass(daoClassName); logger.info(currentDemandeContributionDAO.find(0, 1).get(0).getFiliereDemandeurName());
I get a “ClassNotFoundError”.
Can anyone help me ?
Thanks !
I think the issue is in the way you are creating your DAO.
Here is an example to create a DAO using the BusinessObjectDAOFactory
and the DAO class information:
ProductDAO productDAO = (new BusinessObjectDAOFactory()).createDAO(session, ProductDAO.class);
Note that you must provide user session information as a parameter for the factory.
Also, if possible I would recommend to only use operations if possible. With operations you can search for the existing business data and update it.
First of all I want to highlight that the DAO is provided in Groovy script editor only for read access to the BDM. Update or insert of BDM value is usually done using operation or default value of business variables.
Can you share the full log file content using for example Google Drive, Dropbox…?
Also if you can share your project exported from the Studio as a .bos file that can help me to understand what you are trying to achieve.
Thanks
Hello,
Thank you for your answer.
I want to use a function that I define in the “Groovy scripts” from the Bonita studio. The function should take the map value from the input “contract” and return the corresponding object.
There is an exemple, have a look at the “Step1” operation. In my project the 3 firsts functions work but I want to convert them to the 3 lasts. But I dont know how to properly use the BusinessObjectDAOFactory class.
The main issue is the line :
InvoiceDAO invoiceDAO = BusinessObjectDAOFactory.loadClass(InvoiceDAO.name);
I didn’t test the exemple, it’s only to explain the idea.
https://drive.google.com/open?id=1eWwZk9dgIhtWqunQZY-suujNWJ6CMRxI
I try in an Java project but it was not realy working
I change the object from Product to BDC but the need is the same
I get the following error :
Caused by: java.lang.ClassNotFoundException: com.company.model.BDCDAOImpl
How did you get the APISession
object that is required to create a DAO using the BusinessObjectDAOFactory
?
Actually I tried 2 methods : Within Bonita / With a side project but both doesn’t work for me.
Within Bonita :
`
String className = BDCDAO.class.getName();
logger.info("className : " + className);
BDCDAO currentBdcDAO = (new BusinessObjectDAOFactory()).loadClass(className);
`
I used the loadClass function that doesn’t require the session
With a Java side project :
For the session there is a HowTo about it :
API Engine - Bonita Doc
The code is almost the same :
BDCDAO demandeContributionDAO = (new BusinessObjectDAOFactory()).createDAO(session, BDCDAO.class);
System.out.println("getProjetId " + demandeContributionDAO.find(0, 1).get(0).getCodeBDC());
I used the createDAO function that does require the session
But both gives me the same error
The DAO interface (i.e. BDCDAO
in your example) is part of the bdm-client jar file whereas the DAO implementation (i.e. BDCDAOImpl
in your example) is part of the bdm-dao jar file.
In a test client I create, if I include both jar files in can do for example:
APISession apiSession = loginAPI.login("walter.bates", "bpm");
InvoiceDAO invoiceDAO = (new BusinessObjectDAOFactory()).createDAO(apiSession, InvoiceDAO.class);
List<Invoice> invoices = invoiceDAO.find(0, 1);
Invoice invoice = invoices.get(0);
invoice.setDescription("Test toto");
But if I don’t include bdm-dao dependency I can successfully compile but it failed at runtime.
Note that the session information is mandatory in order for the client to be able to connect to the Engine.
loadClass only try to load the DAO implementation from the current classloader and doesn’t provide an instance of the DAO.
So outside Bonita make sure that you have both libraries.
When running the code from Bonita (for example in a Groovy script called by an operation) you should use the DAO instance available (e.g. the object named for example bdcDAO
). Actually this DAO has been created for your with the current session information. As far as I know as you cannot retrieve current session information from the Groovy script it is not possible to instantiate the DAO.
Hello,
Thank you for the informations, it’s look like you are french so let’s continue in French ?
C’est pas essentiel pour le projet, c’est plus que je souhaite automatiser le procédé :
Le problème que j’ai : sur le projet je vais devoir mettre à jour la donnée (Invoice) à plusieurs tâches humaines et ouvrir chaque opération peut être très rébarbatif,. Dans le cas par exemple ou un attribut est ajouté au model, (ou je doit changer un paramètre) je dois repasser sur toutes les opérations.
Donc j’ai créée une fonction générique dans l’onglet “Développement” > “Gérer les scipts groovy” et je souhaite pouvoir appeler les scripts dans les opérations.
J’ai crée une fonction updateInvoice(Map invoiceInput) qui prend en entrée la map du contrat, puis qui retourne mon objet Invoice. Dans le cas ou c’est un nouvel objet il le crée avec un new Invoice(), sinon il le load avec le DAO, comme dans l’exemple en bas.
C’est donc un script JAVA (Groovy) dans Bonita, mais je n’ai pas accès au DAO dedans, je suis obligé de les passer en temps qu’attributs. Mais si mon objet est amené à changer et à avoir un nouveau attribut qui lui aussi est un objet “Bonita”, je suis obligé d’ajouter une instance de l’attribut en entrée de la fonction. Et donc revenir sur mes opérations pour modifier l’appel aux fonctions.
Je sais pas si c’est très clair mais voila en gros ce que je veux faire. Après je connais pas trop le fonctionnement d’un “classLoader” et j’ai peut être la mauvaise méthode.
<! [Lien pour un exemple de projet] – Links →
[Lien pour un exemple de projet]: https://drive.google.com/open?id=1pvBSwI7YBnWxzsSnUZdh3ebqyS_aRYy7
Merci pour les explications additionnelles votre besoin est clair.
Ce que je propose, afin de ne pas changer la signature de votre méthode Groovy est de lui passer en paramètre une liste de Dao. Tous les DAO hérites de la classe BusinessObjectDAO
vous pouvez donc avoir un paramètre de type List<BusinessObjectDAO>
qui va par exemple contenir InvoiceDAO
et ProductDAO
et par la suite vous pourrez ajouter par exemple CountryDAO
en modifiant seulement le contenu du code de la méthode Groovy. (à la place d’une liste vous pouvez utilisez un nombre d’arguments variable : BusinessObjectDAO... myDAOs
ou un tableau).
Effectivement, les passer par une liste semble être une bonne idée ^^
Merci de votre aide !