Skip to content
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

util-property: create new module with generic bean and property support #163

Closed
hohwille opened this issue Jan 3, 2016 · 14 comments
Closed
Assignees
Milestone

Comments

@hohwille
Copy link
Member

hohwille commented Jan 3, 2016

After years of pain with implementing stupid Java beans with tons of boilerplate code and after some experiments with JavaFx properties I want to start a new approach:

  • create your beans as interfaces
  • instantiate your beans from interface as dynamic proxies via some factory.
  • support for default methods
  • ability for easy fabrication via static method in interface
  • allow JavaFx compatible properties with additional features such as validation and type information.
  • allow read only view on bean
  • support prototype of bean with default values
  • support for dynamic beans that can be extended with properties on the fly (e.g. for JSON/XML binding of new properties added in a new version of a REST-service but not yet known in the type-safe code but still available in the object even after re-marshalling.
  • support for fast, simple and powerful introspection (unlike reflection hell).
  • support both for regular getters/setters as well as property access methods (both via JavaFx conventions as well as DOT.NET style with Capitalized property as method name).

All possible with Java8 today. Approach is worth to be implemented, evaluated and used in practice.
BTW: Would be the perfect solution for mmm-client.

@hohwille hohwille self-assigned this Jan 3, 2016
@hohwille hohwille added this to the release:7.1.0 milestone Jan 3, 2016
hohwille added a commit that referenced this issue Jan 3, 2016
@hohwille
Copy link
Member Author

hohwille commented Jan 3, 2016

Already quite cool for the first approach, still some work to do.
Have a look at the test-case to see what is already working and how to use it, what looks promising to you, etc.
I like that properties can be used to represent and reuse datatypes while no extra effort is required for mapping (JSON, XML, Beans, etc.). It would be relatively easy to add support for Bean in PojoDescriptor, JSON and XML mapping (e.g. Jackson/JSON-B and JAX-B). The question is if there is a way to map such beans with JPA frameworks such as hibernate or OpenJPA... If also that would be possible this would be a really great solution. Otherwise you would still need regular JPA POJOs/Beans and use Property-Beans just for TransferObjects that can implement the same Bean-Interface as the JPA-POJO and allow easy bean-mapping with orika, dozer or map-struct - you would only need to hook into such framework for fabrication. Otherwise the property support makes it so simple that this should not be the big deal.
BTW: I will also add a simple copy method for Bean instances so you could simply create a copy of any bean...
Also I will add a cache for the raw prototypes because the main performance impact is the original creation and introspection when a Bean is created. If that could be cached and only copied prototypes are exposed this could increase performance. A weak reference cache could prevent memory problems.

hohwille added a commit that referenced this issue Jan 6, 2016
hohwille added a commit that referenced this issue Jan 6, 2016
…hods (hashCode, equals, toString), improved test-case (validation, toString)
hohwille added a commit that referenced this issue Jan 6, 2016
…ethod, improved getRequiredProperty exception message, fixed property access.
hohwille added a commit that referenced this issue Jan 6, 2016
@hohwille
Copy link
Member Author

hohwille commented Jan 7, 2016

Initially I am very disappointed that Java did not invent real properties as part of the language.
I did not expect much of the JavaFX properties but in general I am surprised and like them.
However there are some general design aspects of JavaFx properties that I am questioning:

  • First of all the properties themselves have nothing to do with JavaFx. So IMHO a big design mistake was to put them into the JavaFx namespace. java.util.property would have been a much better choice.
  • No build-in support to get the Type/Class of the property value. This is the major reason why we did not use the JavaFx properties as is. If you write generic code and have a property with a value of null then there is no way to determine the actual type of the property. Therefore we changed the design. JavaFx could have made more use of Java8 default methods so we would have to "duplicate" less code but at least the design allows us to do so and be compatible with the entire Property, Expression, Binding and Listener APIs.
  • All number based properties actually bind the value generic to Number. So getValue() always returns Number even for IntegerProperty, LongProperty, DoubleProperty, etc. There might be some good reasons for this decision (I assume simplification of Bindings) but I do not like this design. As I want to be compatible with JavaFx (ObservableIntegerValue, etc.), there is unfortunately no way to change this design.
  • All number based properties do not accept null as value. If you call setValue(null) they actially set the value to 0. I do not see that this was a good decision. Instead we only return 0 in the primitive get() method if value is null but getValue() will still return null.
  • The value of Collection based properties can be set to null. The collection based property itself is also a collection. If you then modify the property via Collection API e.g. using add or addAll method it simply does nothing. This is an awkward case where a default for null would make more sense.
  • Collection based properties themselves implement the Collection interface (List, Set, etc.). However they still hold an ObservableCollection as value that they also delegate their operations to. If the property itself already is a collection, could getValue() not simply return this (the property itself) and the property holds a regular collection internally that is kept private? Maybe because then the semantics of setValue could be in question. I would suggest it clears the internal collection and adds all elements from the given value. But it might be confusing that getValue would not return what you previously passed to setValue. So far this latter point is just a quick thought that might be totally odd.

hohwille added a commit that referenced this issue Jan 8, 2016
…eck if value did not change just like in JavaFx
@hohwille hohwille modified the milestones: release:8.0.0, release:7.1.0 Jan 9, 2016
@hohwille
Copy link
Member Author

hohwille commented Jan 9, 2016

I suggest to move this to 8.0.0 as this requires java8 and that will make it clear and simple:

  • 7.x.y releases are java7 compatible
  • 8.x.y releases require java8.

This should not cause a real large delay but enough to revisit some things before API gets frozen.

@hohwille
Copy link
Member Author

hohwille commented Jan 9, 2016

See also #151 for the milestone aspect.

@hohwille
Copy link
Member Author

Fabrication can take place via static method of interface:
https://github.com/m-m-m/util/blob/master/mmm-util-property/src/test/java/net/sf/mmm/util/bean/impl/example/ExampleBean.java

Also default methods for custom code are supported.

hohwille added a commit that referenced this issue Jan 18, 2016
…ped variable to prevent erasure surprise, binding fix for getValue, GenericPropertyImpl.doSetValue fixed, etc.)
hohwille added a commit that referenced this issue Jan 20, 2016
…ecting interfaces already visited (performance optimization), further renaming
hohwille added a commit that referenced this issue Feb 6, 2016
hohwille added a commit that referenced this issue Feb 6, 2016
…kages (make also property implementations API as they shall be directly used by end users), generic factory support
hohwille added a commit that referenced this issue Feb 7, 2016
@maihacke
Copy link

I played a little bit with your implementation. My first experiment was what will hibernate say to you "proxied" beans. Sadly that's not working, since hibernate does not support mapping of entities which are interfaces (see https://hibernate.atlassian.net/browse/HHH-4413).

@maihacke
Copy link

I forgott beside of this a like the approach, especially the flexibility it gives when mapping json objects, where you can have dynamic properties...

@hohwille
Copy link
Member Author

Thanks for your feedback. I am getting to the point that hibernate is just
too complex and does too much magic behind the scenes such as writing
changes to DB automatically on TX commit. Also classic RDBMS is just pain.
Have a look at orient repo in m-m-m for modern approach with OrientDb.
However for your Usecase you can habe an interface with getters and setters
that you implement as plain JPA bean to work with hibernate. Then you can
also derive a bean interface Form your IF and use that as TO. You can then
use property bindings in UI.
Am 13.02.2016 12:05 nachm. schrieb "Simon Spielmann" <
notifications@github.com>:

I played a little bit with your implementation. My first experiment was
what will hibernate say to you "proxied" beans. Sadly that's not working,
since hibernate does not support mapping of entities which are interfaces
(see https://hibernate.atlassian.net/browse/HHH-4413).


Reply to this email directly or view it on GitHub
#163 (comment).

hohwille added a commit that referenced this issue Feb 17, 2016
hohwille added a commit that referenced this issue Feb 21, 2016
hohwille added a commit that referenced this issue Feb 21, 2016
hohwille added a commit that referenced this issue Apr 12, 2016
…an because operation map was copied as is

#177: improved and refactored: all query stuff including path and expression now in query module, package structure improved, Alias and Variable act as PathRoot that are PathFactory to build path, paths validated to prevent inconsistent paths or queries (needs further improvement), fluent API for property path now without need for type-name in methods, etc.
hohwille added a commit that referenced this issue May 1, 2016
#177: improved
#163: improved
@hohwille
Copy link
Member Author

@maihacke in case you are still interested - here is JPA support and an exmaple:
https://github.com/m-m-m/jpa/tree/master/main/src/test/java/net/sf/mmm/util/query/base/example

hohwille added a commit that referenced this issue Jun 30, 2016
hohwille added a commit that referenced this issue Oct 21, 2016
…default methods to provide dynamic logic (e.g. check a condition and depending on that return one or another regular property). In order to provide initialization code for a regular property the default method can be annotated with @Inject.
hohwille added a commit that referenced this issue Oct 30, 2016
hohwille added a commit that referenced this issue Oct 31, 2016
…-data module in order to decouple property and bean to its final state.
hohwille added a commit that referenced this issue Oct 31, 2016
@hohwille
Copy link
Member Author

hohwille commented Dec 9, 2016

Considered done.

@hohwille hohwille closed this as completed Dec 9, 2016
@hohwille hohwille changed the title uti-property: create new module with generic bean and property support util-property: create new module with generic bean and property support Aug 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants