New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for @ModelAttribute interdependency [SPR-6299] #10965
Comments
Pavel Marinchev commented Basically, the situation when the "foo" model attribute is being bind into getBar(...) method is quite possible according to existed source code (3.0.0-RELEASE). Please, see invokeHandlerMethod(...) method in HandlerMethodInvoker class. Inside this method the invocation of resolveHandlerArguments(...) method uses the the same model being populated with The problem there is that we don't have any guarantee of proper dependencies resolution. Sometimes we get luck and it works, but sometimes not. It depends of how the reflection works. |
Kevin Pearcey commented I have just hit this problem. We have been using this as a 'clean' way to provide typed data into the |
Rossen Stoyanchev commented Couldn't the same be done as follows? @ModelAttribute
public void populateModel(Model model) {
Foo foo = ...;
model.addAttribute(foo);
if( some condition of foo ){
Bar bar = ...
model.addAttribute(bar);
}
} This is equivalent to the referenceData() method mentioned in the forum thread. |
Patras Vlad Sebastian commented They are not equivalent in all cases.
When Also your |
Rossen Stoyanchev commented I see. In that case the original description only partially covers this scenario. What you're looking for is for |
Patras Vlad Sebastian commented I'm not sure that is what the writer of the original description intended. However I only see it useful to have more Obviously you could write a method similar to
However you have to duplicate the meaning of I don't want to hijack this improvement ticket, this should be just about allowing |
Thomas Whitmore commented Hi, I've just run into the same/ related In my case, which is very simple & presumably common:
What I'm finding, is that by quirk of reflection 'buildJobUI' is being found before 'loadOrCreate'; data binding is running, by default, with a newly created instance of Job; 'loadOrCreate' is then skipped, since it's been added to the implicit model by the automatic argument resolution. So, Job is never loaded from the database, 'loadOrCreate' is being skipped, and fields are bound into the wrong object. PS: I wouldn't mind being able to make a "Reference Data" method which didn't have to return any named attribute, but could just populate the implicit model. Can I do this? BTW: I'm not in favour of the idea of "selective model creation" in the slightest, sounds like a complex solution in search of a problem. Thanks guys! |
Thomas Whitmore commented |
John Glynn commented
Indeed, that is one available workaround for the problem. See example posted by Rossen above. |
Ricardo Oliveira commented Having the same problem, this should be classified as a bug. Running the code on Oracle Java 7 will complain about missing default constructor, but running on openjdk 7 works fine. Not sure why different jvms will instantiate session attributes in different order, but this is something that should be fixed. |
Chris Beams commented This sounds related to #14417, where we dealt with similar non-determinism in the ordering of methods from |
Rossen Stoyanchev commented The order in which It is true however that a method marked with We may still want to introduce some predictable order of invocation for the same reasons JUnit 4.11 introduced predictability even though the order of JUnit tests shouldn't matter. |
Patras Vlad Sebastian commented That is why this is an improvement and not a defect. Having a consistent order is a bit different, it is more like a defect. Even though it's the developer's fault, it's better to fail consistently. Still, there's values in implementing either of those. |
Dominic Clifton commented This is related to a bug I raised here: https://jira.springsource.org/browse/SPR-11315 |
Rossen Stoyanchev commented My plan is to check Going a step further, what if an Note that I don't intend to make That said if #10365 works out, such methods invoked after may need to be invoked conditionally, i.e. only after Comments welcome! |
Thomas Whitmore commented Thanks Rossen, I like your proposed plan. While it would add a significant degree of complexity & sophistication internally, at the API level this should provide an “it just works” intuitive extension of the present mechanism. Since the JDK 7 reflection changes, this is really required for non-trivial use of My main concern really is diagnosability -- that the selection & ordering of methods can be logged effectively for debugging. With regard to I am not sure exactly what the best answer is, in this case. But I feel that making pre & post phases of the handler-method into "all the same annotation" & automagically ordering them by dependency graph, may not help developer understanding as to there being an actual & very concrete lifecycle. I don't like whitewash :) Keep up the great work & I am eager to see the results! |
Rossen Stoyanchev commented Thanks for the comments Thomas. We'll make sure the logging information is useful ! Indeed invoking There is a related clarification to be made in this, which is what should happen if an |
Rossen Stoyanchev commented There is a commit in master for the resolution of this issue. See the message for commit 56a82c for details. Note that the solution makes a best effort to find a way to satisfy all inter-dependencies but if there are methods with unresolved dependencies still, those will be invoked in whatever order they happen to be. In other words it remains legal to have an The commit includes a dedicated test class for this issue with a few samples controllers. If there are specific samples you'd like to see or try, please comment here, or send a PR. |
Marten Deinum commented This also solves #15541 (as that is basically a duplicate). |
John Glynn opened SPR-6299 and commented
A common requirement is that a
@ModelAttribute
annotated method be dependent upon another.ie.
Affects: 2.5.6
Reference URL: http://forum.springsource.org/showthread.php?p=263603#post263603
Issue Links:
@ModelAttribute
usage, can prevent@ModelAttribute
initialization of dependent. ("is duplicated by")@ModelAttribute
parameter dependency issue. ("is duplicated by")@ModelAttribute
allowed on attribute in@ModelAttribute
annoted method ("is duplicated by")@ModelAttribute
method to be invoked after the@RequestMapping
method@ModelAttribute
interdependency is still not supportedReferenced from: commits 56a82c1
27 votes, 32 watchers
The text was updated successfully, but these errors were encountered: