Repository navigation
Add an entity option to use fluent setters - #3751
Conversation
|
The entity is one of the core JHipster object, can we discuss this before? I'm not familiar with having a "fluent" setter on a domain object - I see the point, of course, but I've never seen those used on JPA entities, and wonder if there are any drawbacks or issues. Besides, I'm not sure everyone will want those (as I've never seen those used for domain objects), so that would mean dead code for a lot of people. Of course, if there are only advantages, we could also evangelize people to use those more! |
|
Either we should use normal setters or fluent setters, having both might be lot of dead code. I don't see any downside in having fluent setters that follow the same naming convention like below |
|
I think setBar can lead to issues with JavaBean reflection so bar(String bar) would be better. |
|
I thought hibernate would complain if it didn't have the void setBar() method for its reflection but it seems to be OK so maybe we can remove it. |
|
@cbornet what about mapstruct does it play well with this syntax |
|
btw what issue do you foresee with JavaBean reflection? |
|
I don't know, something I read somewhere... |
|
As for mapstruct, I didn't test directly but I guess that it was tested OK by CI. |
|
you need |
|
That's why I duplicated the method. But on in other hand, I removed the |
|
To show the interest of fluent setters, compare Foo foo = new Foo();
foo.setMyString("foo");
foo.setMyString2("bar");
fooRepository.save(foo);with fooRepository.save( new Foo().myString("foo").myString2("bar") );This is a simple example but it gets more and more interesting when structures get complex. Consider Foo foo = new Foo();
foo.setMyString("foo");
foo.setMyString2("bar");
fooRepository.save(foo);
Bar bar = new Bar();
bar.setMystr("bar");
bar.setFoo(foo);
barRepository.save(bar);vs barRepository.save( new Bar()
.foo(fooRepository.save(new Foo()
.myString("foo1")
.myString2("foo2")))
.mystr("bar"));With the fluent version, it almost reads as YAML ! Note: the repository |
|
|
I thought CascadeType.ALL (or persist) was used so that the entity is automatically added to the session. I need to check that again. |
|
If there is no JavaBean setter, Hibernate uses properties directly even if they are private (unlike standard JPA) and Jackson will both serialize and deserialize (as long as there is a getter). My opinion would be to have both |
|
In java.beans.Introspector } else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) {
// Simple setter
pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method);
if (throwsException(method, PropertyVetoException.class)) {
pd.setConstrained(true);
}
}so the void result type is checked before adding the method to the PropertyDescriptor list. |
|
|
I tested that fails with If the void setBar method is not present |
|
It's not really dead code : it's code that people may not use (even if they should 😄 ) and it's in generated code so it's a bit like a library : you don't really need to go see the internal code often. But if you prefer to do it as an option or module I understand. Please tell me which one in that case. |
|
This reminds me that I wanted to add adders and removers on relationships Set. So that could be part of the package. |
|
It's just that people keep telling me JHipster generates too much code, and that they don't understand what is being generated. |
|
So they want awesome features but no code. Like in magic ? If you're ok, I'll do it as a silent option (no question asked) so that it can be configured in jhipster-uml/JDL |
9b2ed04 to
e8df3da
Compare
|
--option might be good. So that people who knows and uses these stuff can Thanks & regards,
|
| this.changelogDate = this.fileData.changelogDate; | ||
| this.dto = this.fileData.dto; | ||
| this.service = this.fileData.service; | ||
| this.fluentMethods = this.fileData.fluentMethods; |
There was a problem hiding this comment.
may be you can add --fluentMethods as an option to sub generator as well when creating entities by hand.
dont forget to PR the JDL project as well
|
Yes, I'll add the command line option. |
|
Done. I'll add it to the JDL once this is merged. |
|
Yes of course. I'm the one who broke it anyway! |
|
I've changed my mind after reading the code: I'm keeping the "fluent-method" option, for backward compatibility (and if people are unhappy with this), but I'm putting it at "true" by default. |
|
I found a couple of small issues, I'll finish this tomorrow! |
|
I'm going to merge this, just a couple of issues I'd like to share before. There was an "add_" method for adding an entity to a collection (for one-to-many and many-to-many relationships), so I added also a "remove_" method:
So for me this needs more testing and practice. |
|
I totally forgot about unidirectional relationships ! We should detect them and not set the remote field for these. |
|
Yes and I broke the build because of this... There must be one edge case I missed. This is quite annoying, I'm wondering if that's the right approach. I'm first correcting the build, but then we must have a look at this, and its consequences. |
|
In fact most of the errors where in our I've also added a ticket to JHipster Core so this is included in the JDL! |
|
@jdubois I wanted to have a look at unidirectional relationships and I couldn't see any issue. |
|
@cbornet I didn't try it after my last comment about it, and the code has changed since, so maybe there isn't any issue after all. If you tried and it works, that's perfect! |
|
Ok. I'll check when I come back. |
|
Oh ! You've already fixed that @jdubois ! 👍 😄 |
|
I don't remember everything I've fixed :-) |
|
Check project Lombok https://projectlombok.org/features/index.html |
|
I was actually kind of suprised that jhipster wasn't already using lombok, seems like that's what all the cool kids are using these days ;) I personally understand the reasons against it, but I've seen it in use in lots of places- |
|
@jdubois @cbornet sorry to beat around the dead horse but just wanted to ask. Since its bean a while that we did this and since no body complains should we make fluent setters the default with |
|
I agree with you, but we don't know what people use: maybe most users still use setters... So, in doubt, I would keep them, even if I agree they should be removed |
|
@jdubois we are tracking it |
|
I just checked, we have 0,01% of people not using fluent methods... If it doesn't do any harm (I haven't checked), let's remove this, OK. |
|
Note : if we remove the setters then we don't respect the javabean contract anymore. Is it not an issue ? (Hibernate and Jackson don't rely on javabean. I think neither does mapstruct) |
|
What we can do is to have fluent setters by default that you can deactivate with --no-fluent-methods. And refactor the User classes. |
|
We also need to cover the UserMapper : our coverage decreased 😭 |
|
@cbornet aren't they already fluent by default? |
|
@jdubois indeed ! |
|
ofcourse I wasnt suggesting we do it now. I just wanted to mention so that I dont forget. I mean we could create only fluent by default and the flag can be used to create non fluent if people want and for user classes we can have only fluent as they are jhipster domain classes. Anyways its not urgent at all. |
Because fluent is much nicer !