Hi folks,
Awhile ago we ran into a doublepost problem with SECAs. The user would be presented with a button to change the status of a Payment to Received. The link would call a service, setPaymentStatus. A lot of important services are bound to setPaymentStatus via SECAs. When the user presses the [Receive] button multiple times in sequence was that all these SECA services would also run multiple times. As a result, we got lots of duplicate data. It's similar to the phenomenon of doubleposts on online forums. We solved the problem by having setPaymentStatus also return the oldStatusId, so we could compare oldStatusId with newStatusId in the SECA definition. It works pretty well. I'm wondering if there is such an ability for Entity ECAs as well? Also, can we solve the double post problem in a more general fashion too? Say we ask if that field has changed at all with, <condition field-name="statusId" operator="has-changed"/> or something similar? - Leon _______________________________________________ Dev mailing list [hidden email] http://lists.ofbiz.org/mailman/listinfo/dev |
It is always a good idea to put good constraints on ECAs to make sure that they execute only when appropriate, like when changing from a specific status to a specific status, for example. The Entity ECAs are not as flexible as the Service ECAs as there isn't as much information available, and the operations involved are lower lever and smaller scoped, so constraining outside that scope is tough. In addition those issues Entity ECAs _always_ run, not just in a particular process, so they should _only_ be used for data maintenance, and preferably not to drive processes... The has-changed operator would be nice, but I'm not sure how it would be implemented... In some way the service engine has to know where to get the before and after values. It's easy to do that in a service implementation though, ie save off the old value before replacing it with the new one, and then pass out the old* value. The problem is the service engine doesn't know where to get the old value. -David On Feb 27, 2006, at 5:51 PM, Leon Torres wrote: > Hi folks, > > Awhile ago we ran into a doublepost problem with SECAs. The user > would be presented > with a button to change the status of a Payment to Received. The > link would call > a service, setPaymentStatus. A lot of important services are bound > to setPaymentStatus > via SECAs. > > When the user presses the [Receive] button multiple times in > sequence was that all these > SECA services would also run multiple times. As a result, we got > lots of duplicate data. > It's similar to the phenomenon of doubleposts on online forums. > > We solved the problem by having setPaymentStatus also return the > oldStatusId, so we could > compare oldStatusId with newStatusId in the SECA definition. It > works pretty well. > > I'm wondering if there is such an ability for Entity ECAs as well? > > Also, can we solve the double post problem in a more general > fashion too? Say we ask if that field > has changed at all with, > > <condition field-name="statusId" operator="has-changed"/> > > or something similar? > > - Leon > > _______________________________________________ > Dev mailing list > [hidden email] > http://lists.ofbiz.org/mailman/listinfo/dev _______________________________________________ Dev mailing list [hidden email] http://lists.ofbiz.org/mailman/listinfo/dev smime.p7s (3K) Download Attachment |
David,
I see why you don't really like EECA, and I don't disagree. The problem we're having is that there's some inconsistency in the code right now over how data is created. For example, sometimes it's created with the delegator directly, sometimes with a create_ service but in a state akin to COMPLETED, or sometimes with a create_ service in a NEW state and then update_ to completed. In this case, is the "EECA" acceptable as the lowest common denominator solution? Or should we think about a "best practices" for creating data in OFBiz. Si David E. Jones wrote: > > It is always a good idea to put good constraints on ECAs to make sure > that they execute only when appropriate, like when changing from a > specific status to a specific status, for example. > > The Entity ECAs are not as flexible as the Service ECAs as there > isn't as much information available, and the operations involved are > lower lever and smaller scoped, so constraining outside that scope is > tough. In addition those issues Entity ECAs _always_ run, not just in > a particular process, so they should _only_ be used for data > maintenance, and preferably not to drive processes... > > The has-changed operator would be nice, but I'm not sure how it would > be implemented... In some way the service engine has to know where to > get the before and after values. It's easy to do that in a service > implementation though, ie save off the old value before replacing it > with the new one, and then pass out the old* value. The problem is > the service engine doesn't know where to get the old value. > > -David > > > On Feb 27, 2006, at 5:51 PM, Leon Torres wrote: > >> Hi folks, >> >> Awhile ago we ran into a doublepost problem with SECAs. The user >> would be presented >> with a button to change the status of a Payment to Received. The >> link would call >> a service, setPaymentStatus. A lot of important services are bound >> to setPaymentStatus >> via SECAs. >> >> When the user presses the [Receive] button multiple times in >> sequence was that all these >> SECA services would also run multiple times. As a result, we got >> lots of duplicate data. >> It's similar to the phenomenon of doubleposts on online forums. >> >> We solved the problem by having setPaymentStatus also return the >> oldStatusId, so we could >> compare oldStatusId with newStatusId in the SECA definition. It >> works pretty well. >> >> I'm wondering if there is such an ability for Entity ECAs as well? >> >> Also, can we solve the double post problem in a more general fashion >> too? Say we ask if that field >> has changed at all with, >> >> <condition field-name="statusId" operator="has-changed"/> >> >> or something similar? >> >> - Leon >> >> _______________________________________________ >> Dev mailing list >> [hidden email] >> http://lists.ofbiz.org/mailman/listinfo/dev > > >------------------------------------------------------------------------ > > >_______________________________________________ >Dev mailing list >[hidden email] >http://lists.ofbiz.org/mailman/listinfo/dev > _______________________________________________ Dev mailing list [hidden email] http://lists.ofbiz.org/mailman/listinfo/dev |
In reply to this post by Leon Torres-2
Oh... forgot to bring up: at a higher level we might also want to consider something like a form submission ID that is kept in the session to prevent double submission of forms. This can be a _real_ pain sometimes when flow control becomes an issue, so it should be optional, but it can be very nice to tell the user that they have doubled submitted, or to disable submit buttons after they have been clicked (this can be really annoying to if it is not done well and doesn't reset on page loads and such). -David On Feb 27, 2006, at 5:51 PM, Leon Torres wrote: > Hi folks, > > Awhile ago we ran into a doublepost problem with SECAs. The user > would be presented > with a button to change the status of a Payment to Received. The > link would call > a service, setPaymentStatus. A lot of important services are bound > to setPaymentStatus > via SECAs. > > When the user presses the [Receive] button multiple times in > sequence was that all these > SECA services would also run multiple times. As a result, we got > lots of duplicate data. > It's similar to the phenomenon of doubleposts on online forums. > > We solved the problem by having setPaymentStatus also return the > oldStatusId, so we could > compare oldStatusId with newStatusId in the SECA definition. It > works pretty well. > > I'm wondering if there is such an ability for Entity ECAs as well? > > Also, can we solve the double post problem in a more general > fashion too? Say we ask if that field > has changed at all with, > > <condition field-name="statusId" operator="has-changed"/> > > or something similar? > > - Leon > > _______________________________________________ > Dev mailing list > [hidden email] > http://lists.ofbiz.org/mailman/listinfo/dev _______________________________________________ Dev mailing list [hidden email] http://lists.ofbiz.org/mailman/listinfo/dev smime.p7s (3K) Download Attachment |
In reply to this post by Si Chen-2
I don't think there is any single answer to this that will work in all cases, but there are some general patterns that should be followed that are often not... 1. in higher level services reuse other services as much as possible, should be considered a high priority in the pre-coding research (and pre-coding research should always be done) 2. if a create/update/delete service exists that should always be used instead of calling down directly to the database; if not used and a entity call is done directly the reason should be documented, even with just a single phrase comment if nothing else In this case I don't really see how an EECA could help, in fact it seems like that would make it more difficult. The best way to handle it, and the way that should always be used for status changes, is to have the service return the oldStatusId and then make sure the statusId (new) and the oldStatusId are very specific, either different plus the statusId is a certain thing, or that the oldStatusId is a certain status and the new statusId is another certain status. I may be missing something here though... How would the EECA help? Is it just for getting around places writing directly to the statusId on the Payment? If so a better approach is to do some general searching and fix the real problems... -David On Feb 27, 2006, at 6:57 PM, Si Chen wrote: > David, > > I see why you don't really like EECA, and I don't disagree. The > problem > we're having is that there's some inconsistency in the code right now > over how data is created. For example, sometimes it's created with > the > delegator directly, sometimes with a create_ service but in a state > akin > to COMPLETED, or sometimes with a create_ service in a NEW state and > then update_ to completed. > > In this case, is the "EECA" acceptable as the lowest common > denominator > solution? Or should we think about a "best practices" for creating > data > in OFBiz. > > Si > > David E. Jones wrote: > >> >> It is always a good idea to put good constraints on ECAs to make sure >> that they execute only when appropriate, like when changing from a >> specific status to a specific status, for example. >> >> The Entity ECAs are not as flexible as the Service ECAs as there >> isn't as much information available, and the operations involved are >> lower lever and smaller scoped, so constraining outside that scope is >> tough. In addition those issues Entity ECAs _always_ run, not just in >> a particular process, so they should _only_ be used for data >> maintenance, and preferably not to drive processes... >> >> The has-changed operator would be nice, but I'm not sure how it would >> be implemented... In some way the service engine has to know where to >> get the before and after values. It's easy to do that in a service >> implementation though, ie save off the old value before replacing it >> with the new one, and then pass out the old* value. The problem is >> the service engine doesn't know where to get the old value. >> >> -David >> >> >> On Feb 27, 2006, at 5:51 PM, Leon Torres wrote: >> >>> Hi folks, >>> >>> Awhile ago we ran into a doublepost problem with SECAs. The user >>> would be presented >>> with a button to change the status of a Payment to Received. The >>> link would call >>> a service, setPaymentStatus. A lot of important services are bound >>> to setPaymentStatus >>> via SECAs. >>> >>> When the user presses the [Receive] button multiple times in >>> sequence was that all these >>> SECA services would also run multiple times. As a result, we got >>> lots of duplicate data. >>> It's similar to the phenomenon of doubleposts on online forums. >>> >>> We solved the problem by having setPaymentStatus also return the >>> oldStatusId, so we could >>> compare oldStatusId with newStatusId in the SECA definition. It >>> works pretty well. >>> >>> I'm wondering if there is such an ability for Entity ECAs as well? >>> >>> Also, can we solve the double post problem in a more general >>> fashion >>> too? Say we ask if that field >>> has changed at all with, >>> >>> <condition field-name="statusId" operator="has-changed"/> >>> >>> or something similar? >>> >>> - Leon >>> >>> _______________________________________________ >>> Dev mailing list >>> [hidden email] >>> http://lists.ofbiz.org/mailman/listinfo/dev >> >> >> --------------------------------------------------------------------- >> --- >> >> >> _______________________________________________ >> Dev mailing list >> [hidden email] >> http://lists.ofbiz.org/mailman/listinfo/dev >> > > _______________________________________________ > Dev mailing list > [hidden email] > http://lists.ofbiz.org/mailman/listinfo/dev _______________________________________________ Dev mailing list [hidden email] http://lists.ofbiz.org/mailman/listinfo/dev smime.p7s (3K) Download Attachment |
In reply to this post by David E. Jones
As Si mentioned, we were thinking that the other solution was to
enforce best practices for service patterns. In the case of a create service, say createPayment in this case, the best practice would be to create it in one specific well-defined initial statusId and no others, say PMNT_CREATED. Then, the status can only be updated with a service devoted to changing the status, setPaymentStatus. That way everyone can bind to setPaymentStatus. Although it is a bit more work in terms of education and refactoring, it might end up being the best solution in the long run. The reason is that later on, we can design classes around these best practices, such as first-order objects for services (instead of the flat, static C-like system used now to define services), interfaces for behaviors, like createEntityRecord, setEntityRecordStatus, and so on. - Leon David E. Jones wrote: > > Oh... forgot to bring up: at a higher level we might also want to > consider something like a form submission ID that is kept in the > session to prevent double submission of forms. This can be a _real_ > pain sometimes when flow control becomes an issue, so it should be > optional, but it can be very nice to tell the user that they have > doubled submitted, or to disable submit buttons after they have been > clicked (this can be really annoying to if it is not done well and > doesn't reset on page loads and such). > > -David > > > On Feb 27, 2006, at 5:51 PM, Leon Torres wrote: > >> Hi folks, >> >> Awhile ago we ran into a doublepost problem with SECAs. The user >> would be presented >> with a button to change the status of a Payment to Received. The link >> would call >> a service, setPaymentStatus. A lot of important services are bound to >> setPaymentStatus >> via SECAs. >> >> When the user presses the [Receive] button multiple times in sequence >> was that all these >> SECA services would also run multiple times. As a result, we got lots >> of duplicate data. >> It's similar to the phenomenon of doubleposts on online forums. >> >> We solved the problem by having setPaymentStatus also return the >> oldStatusId, so we could >> compare oldStatusId with newStatusId in the SECA definition. It works >> pretty well. >> >> I'm wondering if there is such an ability for Entity ECAs as well? >> >> Also, can we solve the double post problem in a more general fashion >> too? Say we ask if that field >> has changed at all with, >> >> <condition field-name="statusId" operator="has-changed"/> >> >> or something similar? >> >> - Leon >> >> _______________________________________________ >> Dev mailing list >> [hidden email] >> http://lists.ofbiz.org/mailman/listinfo/dev > > > > ------------------------------------------------------------------------ > > > _______________________________________________ > Dev mailing list > [hidden email] > http://lists.ofbiz.org/mailman/listinfo/dev _______________________________________________ Dev mailing list [hidden email] http://lists.ofbiz.org/mailman/listinfo/dev |
Leon, Yes, this is pretty much the best practice pattern. A couple of things come to mind in addition to this: - the status change should always be restricted by StatusValidChange records - it is always nice to have a status history table to track status changes and dates; this helps for auditing as well as tracking down errors - having a separate status update service is not necessary for this to work... a general update service can handle this just as well, and for UI purposes even better and cleaner For all of these points see the example component service defs and impls, I guess especially create/updateExample and createExampleStatus. -David On Feb 27, 2006, at 7:21 PM, Leon Torres wrote: > As Si mentioned, we were thinking that the other solution was to > enforce best practices for service patterns. In the case of a > create service, say createPayment in this case, the best practice > would be to create it in one specific well-defined initial statusId > and no others, say PMNT_CREATED. > > Then, the status can only be updated with a service devoted to > changing the status, setPaymentStatus. That way everyone can bind > to setPaymentStatus. > > Although it is a bit more work in terms of education and refactoring, > it might end up being the best solution in the long run. The reason is > that later on, we can design classes around these best practices, such > as first-order objects for services (instead of the flat, static C- > like > system used now to define services), interfaces for behaviors, like > createEntityRecord, setEntityRecordStatus, and so on. > > - Leon > > David E. Jones wrote: >> >> Oh... forgot to bring up: at a higher level we might also want to >> consider something like a form submission ID that is kept in the >> session to prevent double submission of forms. This can be a _real_ >> pain sometimes when flow control becomes an issue, so it should be >> optional, but it can be very nice to tell the user that they have >> doubled submitted, or to disable submit buttons after they have been >> clicked (this can be really annoying to if it is not done well and >> doesn't reset on page loads and such). >> >> -David >> >> >> On Feb 27, 2006, at 5:51 PM, Leon Torres wrote: >> >>> Hi folks, >>> >>> Awhile ago we ran into a doublepost problem with SECAs. The user >>> would be presented >>> with a button to change the status of a Payment to Received. The >>> link >>> would call >>> a service, setPaymentStatus. A lot of important services are >>> bound to >>> setPaymentStatus >>> via SECAs. >>> >>> When the user presses the [Receive] button multiple times in >>> sequence >>> was that all these >>> SECA services would also run multiple times. As a result, we got >>> lots >>> of duplicate data. >>> It's similar to the phenomenon of doubleposts on online forums. >>> >>> We solved the problem by having setPaymentStatus also return the >>> oldStatusId, so we could >>> compare oldStatusId with newStatusId in the SECA definition. It >>> works >>> pretty well. >>> >>> I'm wondering if there is such an ability for Entity ECAs as well? >>> >>> Also, can we solve the double post problem in a more general >>> fashion >>> too? Say we ask if that field >>> has changed at all with, >>> >>> <condition field-name="statusId" operator="has-changed"/> >>> >>> or something similar? >>> >>> - Leon >>> >>> _______________________________________________ >>> Dev mailing list >>> [hidden email] >>> http://lists.ofbiz.org/mailman/listinfo/dev >> >> >> >> --------------------------------------------------------------------- >> --- >> >> >> _______________________________________________ >> Dev mailing list >> [hidden email] >> http://lists.ofbiz.org/mailman/listinfo/dev > > _______________________________________________ > Dev mailing list > [hidden email] > http://lists.ofbiz.org/mailman/listinfo/dev _______________________________________________ Dev mailing list [hidden email] http://lists.ofbiz.org/mailman/listinfo/dev smime.p7s (3K) Download Attachment |
Free forum by Nabble | Edit this page |