tracker issue : CF-4012852

select a category, or use search below
(searches all categories and all time range)
Title:

init() function cannot have required arguments

| View in Tracker

Status/Resolution/Reason: Closed/Fixed/

Reporter/Name(from Bugbase): Alexandre Potvin Latreille / Alexandre Potvin Latreille (Alexandre Potvin Latreille)

Created: 06/25/2015

Components: ORM Support

Versions: 11.0

Failure Type:

Found In Build/Fixed In Build: CF11_Final /

Priority/Frequency: Normal / All users will encounter

Locale/System: ALL / Win 2008 Server R2 64 bit

Vote Count: 15

Listed in the version 2016.0.0.297996 Issues Fixed doc
Related Bugs:
CF-4090267 - Similar to


Problem Description: 

    entityNew, entityLoad and entityLoadByPk cannot be used if entities have an init() function with required arguments

Steps to Reproduce:

    1. Define a persistent component with an init function that has required arguments
    2. Make sure that there is already an existing record in the database table to which your entity is mapped
    3. Call entityLoad('SomeEntity')

Actual Result:

    ColdFusion throws a coldfusion.runtime.MissingArgumentException

Expected Result:

    The rehydrated entity instances are returned

Any Workarounds:
    
    1. Create a Factory for every entity which will be responsible for enforcing the required arguments. The Factory will have to be in the same package of the entity since we will want to mark the init method as package protected to avoid allowing the creation of the entities using the new keyword.

    Downside: Creating a Factory for every entity is a burden and the business logic for every entity will now have to be spread across at least 2 components when most of the time it would be unnecessary.
    
    2. Set the initmethod component attribute of the entity to initNoArgs. Create an init method with required arguments to use as the business constructor and revert back to the old createObject('component', 'SomeEntity').init(...) syntax for creating entities.

    Downside: One could easily forget to call the init method while this is much less probable when using the new keyword.

----------------------------- Additional Watson Details -----------------------------

Watson Bug ID:	4012852

External Customer Info:
External Company:  
External Customer Name: Alexandre
External Customer Email:  
External Test Config: My Hardware and Environment details:

Attachments:

Comments:

This bug is quite a show stopper for anyone that is serious about following Domain-Driven Design paradigms. Always-valid entities makes it much easier to reason about the domain. I understand that not calling the initmethod from orm functions would break backward compatibility, but we would just need a configuration setting allowing to specify the behavior.
Comment by External U.
6953 | June 25, 2015 11:11:21 AM GMT
+1 Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters Vote must be between 25 and 4000 characters
Vote by External U.
6997 | June 26, 2015 12:34:23 AM GMT
I can understand the usecase for EntityNew. What would be the usecase for EntityLoad ? Do you use this with your proposed workaround? Can you provide any sample code?
Comment by Nimit S.
6954 | June 26, 2015 04:59:03 AM GMT
@Nimit Sharma I do not think code samples are required. The use case is simple for EntityLoad; if a persistent component has a constructor with required arguments then EntityLoad will throw a coldfusion.runtime.MissingArgumentException when trying to create the components. In the workarounds that I propose, the persistent components will not have an init method with required arguments so that EntityLoad can be used.
Comment by External U.
6955 | June 26, 2015 07:57:22 AM GMT
On reflection, I don't think it's appropriate for functions that retrieved previously-stored objects should call the constructor: entityLoad() is not creating a new object, it's just bringing one back from storage. There is probably a case for event handlers which can cover pre- and post- storage requirements though, like PHP's __sleep() and __wakeup(): http://php.net/manual/en/class.serializable.php. But don't give them such crap names. Probably beforeSave() and afterLoad(). There may be in-memory tasks that need to be performed either side of storing/loading an object.
Comment by External U.
6956 | June 27, 2015 01:14:42 AM GMT
@Adam Cameron That is exactly my point, the constructor should not be called by entityLoad. Hibernate needs a default no argument constructor to work, but since java supports function overloading that is not an issue since you can create one without arguments that is private and have another one with required arguments that is public. Since Hibernate uses reflection, it can invoke the private no arguments constructor without issues. Changing the behavior of the ORM functions in CF would break backward compatibility, but if they could simply introduce a configuration option to change the behavior so that constructors aren't called that would be enough.
Comment by External U.
6957 | June 27, 2015 08:02:28 AM GMT
They can break backwards "compatibility" here no problem. CFML is not Java, and there is no *requirement* for any constructor to be run in CFML. The issue is that Adobe was calling the init() function or initmethod erroneously in these situations. If anyone was possibly relying on this buggy behaviour (and is there any proof of this to be the case, btw?), then more fool them. Don't leverage bugs. It'll also come out in their testing before they upgrade / apply the patch. Adobe's burden here is to: 1) fix the bug 2) document the change in behaviour clearly in the release notes. -- Adam
Comment by External U.
6958 | June 27, 2015 10:08:52 AM GMT
Well that just sucks!..........................
Vote by External U.
6998 | June 29, 2015 05:14:53 AM GMT
@Nimit Sharma, Could we have an update on this issue? Thanks!
Comment by External U.
6959 | July 08, 2015 02:52:52 PM GMT
@Nimit Sharma When can we expect this to be fixed?
Comment by External U.
6960 | August 02, 2015 02:56:07 PM GMT
Alexandre: If your ORM entities need additional data to be fully operational (i.e.: injected services, settings, etc) another option is to simply use a DI engine like WireBox to handle this injection. This will allow you to move from constructor injection entirely and go to mixin injection which will make required constructor args a non-issue. That said, I disagree that CFML is not required to run a constructor. The code tasked with prepping a component for operation (the constructor) is a behind the scenes concern and should run on every component instantiation regardless of why or how it's being created. (If it's being populated with persisted entity data is irrelevant) The shoddy legacy behavior of not having a proper constructor is an unfortunate embarrassment in the history of CFML that I've been happy to see made right in newer functionality. Calling a constructor should never be a bug and it is fair to assume it will always happen. If need be, I'd say add an additional argument to these functions to be able to pass along some constructor arguments to be used when instantiating the components. > we will want to mark the init method as package protected to avoid allowing the creation of the entities using the new keyword. TBH, this is CFML, not Java. If you don't want an object created via the "new" keyword, don't do it! And what would be wrong with that anyway? It shouldn't matter _how_ a CFC is instantiated-- all methods should be identical in execution and equally valid.
Comment by External U.
6961 | August 02, 2015 06:57:27 PM GMT
@Bradley I'm not sure that you correctly grasp the problem. My entities do not need injected services (it's a very bad practice to inject services in entities by the way), they only require the data necessary to fulfill their invariants and their role. The role of a constructor is to force the initialization of the variables of an object so that it cannot be constructed in an invalid state, meaning all it's invariants are respected. Objects that do not require arguments to be created are very rare. The role of an ORM is to reconstruct those objects and rehydrate their in-memory state from their persisted state, without leaking infrastructure details in the entities if possible. > "Calling a constructor should never be a bug and it is fair to assume it will always happen." The problem here is that ColdFusion ORM is based on Hibernate, which has been designed for Java which supports constructor overloading. Therefore, you only need to declare a private no arguments constructor and Hibernate will use it to construct your objects through reflection. You would also implement another public constructor that requires the data the object needs and that's the one used in code. However, you cannot use this approach in ColdFusion, since it doesn't support method overloading. Therefore, the current ORM implementation in ColdFusion is flawed: it cannot support objects with required constructor arguments. I'll re-state what Adam Cameron said in a comment below, since I totally agree with the statement: > "CFML is not Java, and there is no *requirement* for any constructor to be run in CFML. The issue is that Adobe was calling the init() function or initmethod erroneously in these situations." - Adam Cameron
Comment by External U.
6962 | August 02, 2015 11:43:06 PM GMT
> My entities do not need injected services Then what is it that you're getting via the constructor args? No matter, it doesn't invalidate my answer. *Whatever* it is that you're passing in for whatever reason, you can use a DI engine like WireBox to eliminate the need for constructor args. I personally avoid constructor args entirely as they require more boilerplate to use and complicate composition. > (it's a very bad practice to inject services in entities by the way) they only require the data necessary to fulfill their invariants and their role. Really? I'd say you have a rather narrow view of of best practices and design patterns. There's absolutely nothing wrong with a bean using a service (or a setting, logger, ioc container, etc) to accomplish its tasks. In fact, I personally subscribe to the mantra, "Fat beans, slim services, and even slimmer controllers". > The role of a constructor is to force the initialization of the variables of an object so that it cannot be constructed in an invalid state That's a bit stricter definition than I'd go with, but overall, yes-- which underscores the the reason why constructors should _always_ be called on new instance creations to ensure the object is in a valid state. I don't understand how you can say this, but then suggest that "in this case" we should just skip the constructor! > Objects that do not require arguments to be created are very rare. According to whom/what? I never use constructor args. Mixin injection is much easier, cleaner, and fitting for a dynamic language like CFML. Perhaps that statement would be true if we were discussing Java-- a language generally wrought with unnecessary boilerplate and pedantry. > without leaking infrastructure details in the entities A constructor arg isn't an leaked "infrastructure detail"-- it's the declared *public API* for creating the class. If you wish to create an instance of a class for *any reason* you must obey it's API. > However, you cannot use this approach in ColdFusion, since it doesn't support method overloading. You don't need to overload method in ColdFusion, use optional arguments. Java must overload because all arguments are required, but CFML bears no such rule. > Therefore, the current ORM implementation in ColdFusion is flawed: I don't understand your logic. Neither Java/Hibernate or CF allow you to create ORM entities with required arguments. The solution for each is consistent with that language. i.e., in Java, overload the constructor and in CF, make your arguments optional. What's the issue here? > it cannot support objects with required constructor arguments. Neither can Java. What's your point? It could however, if the functions listed in your ticket were modified to accept a collection of constructor args to pass along to entities. > I'll re-state what Adam Cameron said in a comment below, since I totally agree with the statement I'm sorry, but Adam is wrong. If an object has a constructor, it should *always* be called. This (sadly) didn't use to be the case with createObject(), but Adobe made things right when they implemented ORM and it would be a horrible behavior for some ORM functions to initialize the component and others not to. At end of the day, if your object is able to be usable without it's constructor args, *make them optional*! Recommending that CF simply stop calling the constructor is, in my opinion, a very very wrong approach to fixing this issue for yourself.
Comment by External U.
6963 | August 03, 2015 06:12:40 PM GMT
@Bradley > "At end of the day, if your object is able to be usable without it's constructor args, *make them optional*! " That's the point, the objects are NOT usable without their arguments, hence they need to be required. Imagine a simple value object such as Money. Doing 'amount = new Money()' would make no sense so why would it be allowed? Now imagine an Auction entity that has a starting price and allows to place bids. Allowing 'auction = new Auction()' would also make no sense since having a starting price is an invariant of an Auction, it needs that data to fulfill it's role. Without that data, invoking behaviors on that object such as 'auction.placeBid(bidder, amount)' could lead to unpredictable results or exceptions. Therefore, it's a reasonable idea to prevent creating an Auction without it's starting price: startingPrice = new Money(10.00); auction = new Auction(startingPrice); The problem at this point is that you will be able to persist the Auction entity through CF-ORM, but you will not be able to load back the entity (while this is possible in Java with Hibernate). What's the point of having an ORM that cannot fulfill it's role? An easy fix would be to avoid calling the constructor when rehydrating the object. That behavior could be based on configuration options to avoid breaking backward compatibility, but they need to fix that problem which is a serious bug in their ORM implementation.
Comment by External U.
6964 | August 04, 2015 07:19:42 AM GMT
> That's the point, the objects are NOT usable without their arguments "Usable" and "populated" are two separate concerns and you're confusing the two. ORM sets the data into your object after creation, so if you are going to create an entity, it must be able to be created with no constructor args and then populated. That's just how it is, whether you are in Java or CF. I don't understand your refusal to acknowledge that. > Doing 'amount = new Money()' would make no sense Why wouldn't that make sense? I would expect the value of the money to be null or 0 depending on how you implemented it. > Allowing 'auction = new Auction()' would also make no sense Why wouldn't that make sense? Perhaps bidding hasn't started, so there is no starting bid-- or better yet it should default to zero. You're forcing uneccessarily strict and pedantic rules upon yourself to force an issue that really isn't there. Many people use populator helpers in their MVC frameworks to populate beans for them (usually via setters) so there's many cases in which an object may be initialized but not populated with data yet (other than its defaults). > but you will not be able to load back the entity (while this is possible in Java with Hibernate). Yes, it is possible! Why do you keep ignoring the solution I've told you over and over. You must allow for a constructor can be called without arguments in BOTH languages. In Java you overload, in CF you use optional args. This is how each language works. CFML is not Java, so please stop trying to force it into a Java mold. > What's the point of having an ORM that cannot fulfill it's role? CF ORM _can_ fulfill its role. You're sticking your head in the sand and ignoring the obvious solution. > An easy fix would be to avoid calling the constructor when rehydrating the object. No. No. No. Just, No. You're ignoring the possibility that the constructor does more than simply setting data into the object. Constructors can set up default internal data structures, configure loggers, acquire dependent services, or anything else imaginable. Just because you have no instance data to pass in doesn't mean you should simply not call the constructor. Even in Java-land, there's nothing to say that your overloaded constructor with no args doesn't still do important things to make the object usable. I'm honestly surprised that you're being so diehard about doing things the "right way" (or at least the Java way) yet suggesting that a constructor should not be called! That's like an OO sin. > which is a serious bug Hardly. CF ORM's treatment of constructors is identical to Java's. You simply need to use the appropriate technique for each language to call a constructor with no arguments.
Comment by External U.
6965 | August 04, 2015 01:14:09 PM GMT
@Bradley I guess we will have to agree to disagree. You seem to have a very different philosophy on what proper OO is. I adhere to the always-valid entities camp while you aren't and that's fine, but perhaps this is the cause of our misunderstanding. > "Perhaps bidding hasn't started, so there is no starting bid-- or better yet it should default to zero." It always depends on the real domain, but I assumed for my Auction fictional domain that the first bid couldn't be lower than the startingPrice. Therefore, having a starting price is an invariant of an Auction that needs to be protected at all times. I also prefer things to be explicit rather than implicit, if I want an auction to start at price 0 then let it be with new Auction(new Money(0)). > "Yes, it is possible! Why do you keep ignoring the solution I've told you over and over. You must allow for a constructor can be called without arguments in BOTH languages. In Java you overload, in CF you use optional args. This is how each language works." Perhaps you misunderstood the problem, which is: Entities cannot have required arguments if you whish to leverage the native ORM features. Your solution: Ignore the problem and make arguments optional. In Java the solution doesn't require you to ignore to problem since the private no arguments constructor becomes an infrastructure concern only meant to be called by Hibernate an invisible to the business code. That's the infrastructure compromise to make in the domain in order to use that tool. Therefore, client code using the objects still have to go through the public business constructor which has required arguments and prevents the creation of those in an invalid state. In ColdFusion, the only possible workarounds are the one I already described in the bug description and they are not very practical. Finally, I'm only advocating that the constructor should not be called by the rehydration process because that seems to be the most practical solution to the problem in ColdFusion. I'd be happy with any solution that allows enforcing required arguments in constructors.
Comment by External U.
6966 | August 04, 2015 02:20:11 PM GMT
@Bradley I've been thinking a little more about it and despite what I said at the end of my previous message, I do specifically advocate against calling the constructor during the rehydration process after all. A constructor has the semantic of creating a new object and some objects might rely on that semantic to tell the world that they have been created. For example, an Auction constructor could run some code like this.events.raise(new NewAuctionAvailable(...)) which would be handled by code interested by the fact a new auction is available. Rehydrating an object doesn't create a new one (from a business perspective), it only rehydrate the state of an already existing object, giving the impression that the object never left memory. The difference is subtle but very important. Calling a constructor during the rehydration process is like calling a constructor after an object already has been initialized. It's a buggy behavior that needs to be fixed.
Comment by External U.
6967 | August 05, 2015 07:33:20 AM GMT
Just because an operation is abstracted away from you doesn't mean it doesn't happen! You keep using the word "rehydrated" as though hibernate wrings the water from your entities and sticks them on the shelf. Hibernate is a persistence framework that has well-documented the fact that it does not serialize entire class instances, but instead extracts their data and stores it in a database until it needs to reconstruct the class and re-populate it. Just because ORM encapsulates that functionality from you does not license you in invent a new reality where you can pretend your objects "never go away". This isn't true in Java Hibernate and it isn't true in CF ORM. If your application needs to announce the event of a new auction being available, that would be better suited for the first time it was persisted, or the first time it's status was changed to available. You're conflating the creation of the logical dataset with the back-end allocation and configuration of data in your server's heap. A logical 'auction' may only be created once, but it's reasonable to assume the class that represents that auction may be constructed thousands of times over the course of your application's life. And every time that component instance is constructed, it's constructor should be called. Every. Time.
Comment by External U.
6968 | August 05, 2015 11:45:38 AM GMT
This is hilarious. Keep going guys. Really.
Comment by External U.
6969 | August 05, 2015 12:14:30 PM GMT
@Bradley I had started to write back and express my point of view differently, but I believe that at the end we would still be forced to disagree and would be stuck in an infinite argumentation loop. To avoid a stack overflow, I think we can agree that what's important is just that CF-ORM allows to store and retrieve entities that have required arguments. Not being to do is overly limiting and forces you towards a specific programming style. Making arguments optional (what you proposed) is obviously not a viable option since it's only avoiding the problem altogether.
Comment by External U.
6970 | August 05, 2015 03:04:48 PM GMT
CF ORM's behavior is same as Java/HIbernate. The entity class must have a no argument default constructor. Closing the bug.
Comment by Rupesh K.
6971 | August 31, 2015 12:59:00 PM GMT
@Rupesh Kumar That's not a valid reason, Hibernate works like that in Java because there's no way to instantiate an object without going through a constructor in that language. ColdFusion doesn't have this restriction at all, as long as `createObject` is supported. Anyway, what about giving the ability to configure an `ormInitMethod`, just like we can configure an `initMethod`. Any function can be a constructor in ColdFusion and adding this additional configuration option would solve all the problems.
Comment by External U.
6972 | September 01, 2015 08:31:28 AM GMT
Agree with this: "That's not a valid reason, Hibernate works like that in Java because there's no way to instantiate an object without going through a constructor in that language. ColdFusion doesn't have this restriction at all, as long as `createObject` is supported." Both Brad and Rupesh are applying rules meant for Java to CFML. If CFML had been implemented that the init() method actually was a true constructor - which it *isn't* - then they'd have a point. But it's not, so you don't. CFML has no requirement for a constructor to run to create an object - and there's nothing actually wrong with this! - so therefore there's no need for CFML to apply a rule that was only ever down to a vagary/restriction of Java's OO implementation. If it was possible to not run any constructor at all in Java, I'm sure that's what Hibernate would be leveraging. However it's stuck to playing within Java's restrictions. But it's not equivalently restricted in CFML, so don't enforce something that's unnecessary. You're both wanting to enforce rules for the sake of rules, and reading from the wrong rule book whilst doing so.
Comment by External U.
6973 | September 01, 2015 08:49:16 AM GMT
@Rupesh Kumar *BUMP*
Comment by External U.
6974 | September 09, 2015 11:43:37 AM GMT
Since the object is created by the ORM framework, it has to ensure that object is fully constructed and properly initialized. The constructor must be called so that any initialization required can be done. So we follow the same rule that Hibernate or any other ORM frameworks follow. I see your point on constructor overloading that is possible in Java but not in CFML. Adding "orminitMethod" with fallback to "initMethod" would solve this problem. What do others think? We would open this one but wait for inputs from others.
Comment by Rupesh K.
6975 | September 09, 2015 10:33:40 PM GMT
Ideally the `ormInitMethod` would have to be configurable at the application level through the `ormSettings` as well as directly on a component. When placed on a component, it would be nice if the attribute was inheritable. This would allow to configure the setting for entire object hierarchies - that would give an additional level of flexibility. The closest configuration shall always win.
Comment by External U.
6976 | September 10, 2015 08:21:20 AM GMT
This bug impacts productivity because all the potential workarounds are adding a lot of boilerplate and unnecessary complexity to the code base. Being forced to create factories or builders for every single objects where a simple constructor would have been sufficient is a real pain.
Vote by External U.
6999 | September 15, 2015 01:38:49 PM GMT
settings inheritance is always a good idea +1
Vote by External U.
7000 | September 16, 2015 09:20:44 AM GMT
I believe that settings inheritance is a good way to speed up development +1
Vote by External U.
7001 | September 16, 2015 09:29:16 AM GMT
+1 This would be very helpful
Vote by External U.
7002 | September 16, 2015 09:29:35 AM GMT
+1 for settings inheritance!
Vote by External U.
7003 | September 16, 2015 09:33:54 AM GMT
+1 this is needed .
Vote by External U.
7004 | September 16, 2015 09:34:40 AM GMT
The attribute would be inheritable
Vote by External U.
7005 | September 16, 2015 09:35:07 AM GMT
+1 We require this feature to enhance the development speed
Vote by External U.
7006 | September 16, 2015 09:36:44 AM GMT
+1 Yes to this! It would be great!
Vote by External U.
7007 | September 16, 2015 09:37:13 AM GMT
+1 This would be good to have
Vote by External U.
7008 | September 16, 2015 09:37:35 AM GMT
Good idea! This is a necessary feature.
Vote by External U.
7009 | September 16, 2015 09:48:06 AM GMT
+1 Vote must be between 25 and 4000 characters
Vote by External U.
7010 | September 16, 2015 09:49:22 AM GMT
+1 .
Vote by External U.
7011 | September 17, 2015 08:26:21 AM GMT
I think Rupesh's suggestion -- to add a new way to specify an ORM-specific constructor -- is a great idea but I agree with Alexandre that we should be able to specify an application-wide default value for it too (and override on a per-CFC basis if we want).
Comment by External U.
6977 | October 06, 2015 10:37:44 AM GMT
Agree with Alexandre's suggested modification to Rupesh's original idea.
Comment by External U.
6978 | October 06, 2015 10:40:38 AM GMT
Sounds good. We would take it up for CF12.
Comment by Rupesh K.
6979 | October 06, 2015 11:21:22 PM GMT
Thank you Rupesh! That's great news!
Comment by External U.
6980 | October 06, 2015 11:33:08 PM GMT
@Rupesh No chances to make it a patch for CF11? We just upgraded from CF9 to CF11 so I don't see us upgrading to CF12 anytime soon. PS: Not that I really care, but to avoid the confusion, I'm the one who first suggested the "ormInitMethod" fix.
Comment by External U.
6981 | October 14, 2015 09:25:03 AM GMT
Alexandre, since you need clarification, here's what Adam and I meant: Rupesh agreed to do this: "Adding "orminitMethod" with fallback to "initMethod" would solve this problem." And your suggested modification was: "Ideally the `ormInitMethod` would have to be configurable at the application level through the `ormSettings` as well as directly on a component."
Comment by External U.
6982 | October 14, 2015 11:29:12 AM GMT
Usually enhancements are added to the new upcoming release only. So as of now it wouldn't be added to the CF 11.
Comment by Rupesh K.
6983 | October 14, 2015 12:27:18 PM GMT
@Rupesh Kumar Well, the fix may look like an enhancement, but it's to fix a buggy behavior that has no practical work-around. @Sean Corfield "I think Rupesh's suggestion -- to add a new way to specify an ORM-specific constructor is a great idea " I'm just saying that it isin't Rupesh's suggestion, it's mine which I posted in the comments on 7:01:28 AM GMT+00:00 Sep 1, 2015
Comment by External U.
6984 | October 16, 2015 12:18:15 PM GMT
@Alexandre, FFS, I already explained what I was agreeing with: the specifics of Rupesh's very concrete proposal. I am perfectly capable of reading the entire thread. You did NOT suggest what Rupesh actually proposed. You suggested something else that was not a complete idea. Stop being so sensitive!
Comment by External U.
6985 | October 16, 2015 01:24:05 PM GMT
@Sean Sensitive? I only care about accurate facts ;) Perhaps you could explain how: "Adding "orminitMethod" with fallback to "initMethod" would solve this problem" (Rupesh's proposition) is so much more concrete and complete than: "what about giving the ability to configure an `ormInitMethod`, just like we can configure an `initMethod`" (my initial proposition)? The only difference I can see was the explicit mention of a fallback to initMethod, which was already implicit to avoid breaking backward compatibility...
Comment by External U.
6986 | October 16, 2015 02:42:17 PM GMT
Hands up who thinks any of the last few messages here (except for Rupesh's) are a waste of everyone's time? Do they change the likely outcome of this ticket? Serious, chaps? Thanks Rupesh for seeing this thing through.
Comment by External U.
6987 | October 16, 2015 04:59:17 PM GMT
*this message is irrelevant to the current issue* @Adam That's a bit ironic to post a message even less relevant to complain about not so relevant messages. However, you have a good point and I hope Adobe will realize the lack of supporting communication mechanisms and features in Adobe's Bugbase. Not every bit of a discussion will have a high relevance to the core subject, especially when there's only one communication channel. If we push it further we can also see that comments that were once relevant during a specific discussion phase become irrelevant as the discussion evolves. Ticket phases are merely expressed by statuses in Adobe's Bugbase, but those phases could be much more explicit and be part of the actual ticket's resolution workflow (e.g. acceptance, proposals, etc.). Anyway, that's another story, but this system would clearly benefit from a deeper domain analysis...
Comment by External U.
6988 | October 17, 2015 09:18:23 AM GMT
Introduced an orminitmethod which will be called on initialization of an orm entity using EntityNew. This can be set using component property as well. eg:-<cfcomponent .... orminitmethod = "orminitfunc"> The orminitfunc function should not have any required arguments. With this, developers can use an initmethod with required arguments to be used when creating an entity using NEW and an orminitmethod (with no required args) to be used by CF ORM.
Comment by Himavanth R.
6989 | November 02, 2015 08:39:45 AM GMT
@Himavanth That's great! What are the various ways of configuring the ormInitMethod? You said "This can be set using component property as well", but you haven't mentioned how else this may be configured. Will there be a way to configure this for an entire application? Will the ormInitMethod attribute be inherited by subcomponents? Thanks!
Comment by External U.
6990 | November 02, 2015 09:27:46 AM GMT
I also forgot to ask: was the current behavior considered a bug after all or it will only be implemented in CF12 as a feature? We would really benefit from a patch for CF11 in here: we might be stuck with CF11 for a while and this issue is killing us. It would be quite disappointing to not even be able to benefit from our own opened issues...
Comment by External U.
6991 | November 02, 2015 09:43:32 AM GMT
This issue is fixed and the fix will be available as part of next major release of ColdFusion. We have introduced a property "orminitmethod" at component level to address this issue. Subcomponent do not inherit orminitmethod. It behaves exactly like initmethod. I have logged another tracking bug #CF-4090267 to have an application level setting
Comment by Nimit S.
6992 | November 20, 2015 07:38:05 AM GMT
"Subcomponent do not inherit orminitmethod. It behaves exactly like initmethod." Does that make sense? (either behaviour)
Comment by External U.
6993 | November 20, 2015 08:22:06 AM GMT
Yes, I think that is reasonable. It's the _setting_ that is not inherited (the method will be). If you override the function, you need to explicitly state whether you intend the init behavior to apply to the override (since the code that uses the old CFC type will not be affected by the extension -- so this only applies to new code using the new CFC).
Comment by External U.
6994 | November 20, 2015 01:15:07 PM GMT
OK, so Sean you think that only properties / methods etc should have the concept of "inheritance" applied to them, and not "settings"? I'm not disagreeing, but why is this the case?
Comment by External U.
6995 | November 23, 2015 03:16:56 AM GMT
As far as I know, none of the attributes on (cf)component are inherited and if you look at them, most of them wouldn't make any sense to inherit anyway (extends, inherits, nearly all of the ORM-related stuff). Since the vast majority don't make sense to inherit, consistency says none of them should inherit.
Comment by External U.
6996 | November 23, 2015 03:04:26 PM GMT