Hi Jonathan,
thanks for your ideas and remarks, some comments inside..

Am 01.03.2013 21:39, schrieb Jonathan Fuerth:
Hi again Thomas,

I just want to ask again up front: can we have this discussion on errai-dev or forge-dev? I think there are a bunch of interested people who could provide additional valuable feedback.

On Thu, Feb 28, 2013 at 5:14 PM, Thomas Frühbeck <fruehbeck@aon.at> wrote:
Hi Jonathan,
you shouldnt count _every_  artifact related to an entity:
    - 1 Service Interface
    - 1 Service Impl (1 serivce impl is to be omitted)
    - 1 Mapping
    - 1 Wrapper
    - 1 Reference for relationship transport
    - 1 edit form
    - 1 search form
    - 1 html file
did I miss something? you cant do CRUD on server w/o some server logic, and honestly, do you mean to stuff all UI into one class? can't imagine that. It's feasable, I tried to go that direction, but the handling of @Bound (@Data) fields becomes quite tricky, taking into account all the validation and compilation steps.

No, I wouldn't want to stuff all the UI into one class. I like the idea of having a separate @Templated form for each entity. For that matter, I even like the idea of keeping separate search, edit, and read-only @Templated classes. But I don't think I would end up needing all of those for each entity type.
Hm, on one side there are entity specific DataField / search related elements that simply aren't generic.
On the other side I tried to rely on inheritance, but as I understood "Errai Marshalling always works from fields when discovering properties." - which means _declared fields_, this may be seen also in the DefaultJavaDefinitionMapper.map().
Although I can imagine that this may be necessary, it doesn't help to write generic nonredundant code.

But I agree, quite verbose :-/ Just now I am extending a generated project for a real world project, and I start to suffer already :-)

Yes. As a practical example, I'm imagining what I would do to improve the usability of the Sakila app. Starting with the scaffolding as generated, I would probably delete more than half of what was generated. Quick brain dump:

I'd keep the Films, Actors, Stores, Staffs and Customers as top-level places in the UI.

I'd make Address, Language, Category, Country, and City work as auto-complete fields instead of hard references that you have to create first. Maybe in an admin screen, there could be the opportunity to list these things and delete them.. but probably not. I'd probably just write a routine that deletes the orphaned entries periodically.

Good point! Perhaps I could identify such entities by number of attributes and references?
Simple entities could well be used in this way.
I'd integrate Rentals and Inventories into the Films, Stores, and Customers views, showing the details appropriate to each of those contexts (for example, in a list of Stores, we'd just see the rental count; in an individual store page, we could see more details perhaps in a table of Rental entries grouped by film title and sorted by % inventory utilization or something).


One thing that I notice from this little thought experiment: it would be useful to have a generator for an autocomplete textbox for a particular entity type. This would search by one or more attributes of the entity, resolving the existing entry if the user picks a completion, or creating a new one if the user doesn't pick a completion. I've already had to implement this a few times by hand in various Errai demos. For example, see the 'department' field in ItemForm: https://github.com/errai/errai/blob/master/errai-jpa/demos/errai-jpa-demo-grocery-list/src/main/java/org/jboss/errai/demo/grocery/client/local/ItemForm.java

The other thing I notice is that composability of the @Templated components is really important. I think they're already nicely composable, so this is more of an observation than a recommendation. :)
One thing makes me uneasy: I have to provide a data-field for _every_ @DataField property I could possibly use, so the template and the @Templated is tied together.
But modularity is great here.
 
It _really should_ be possible to hide complexity and boiler plate at least for the Wrapper/EntityReference classes, they are really bad!

Yes, I think we should lean on the Errai framework itself to deal with these issues (either by 3-way diff or generated proxies or a mix of both). I don't think it's good to have the generated proxies (or really any generated code that's not meant to be edited by hand) mixed in with the application sources.

I had a look at the code generation, I will try to start on it.

Let me say: Errai is really great, I'm glad we met!!
But there are hard limits, which are not easy to come by (no server only code, static factory, field dependency for mapping generation)

I don't understand what you're referring to here. (but I do agree there will inevitably be hard limits to what the framework can do) 

The point is:
   - static factory method of entities: "Otherwise, if the entity has a public static method where every argument is annotated with @MapsTo"
       you just don't get JPA entites readily supplied that way, and I do not want to alter JPA entity code - think of EJB Jars supplying entities

   - even if I implement a static factory method, it cannot contain "server only" non GWT-compatible code, there is no clean way to pass a Builder to the MappingDefinitionFactory

   - field dependency: see "declaredField"  vs.  inheritance above


Regarding entity relationship: I will have a look at generated proxies, I hadn't seen the dynamic code generation yet. I am just starting reading about it.
Do you think it is possible to generate a proxy object for an entity, which "unfolds" itself when accessed by retrieving its data on demand from server?
Perhaps you have an example?

Yes, it's definitely possible to do that, but the fetching of new data would have to be asynchronous. The proxies wouldn't be terribly transparent.. code that uses them would need to use callbacks when traversing lazy-loaded relationships.

A feature like this would overlap the capabilities of the datasync feature I'm planning quite a bit. That's not necessarily a bad thing, of course!
Yes, definitely a positive overlap :-) I am looking forward to.


I do not really like the "wrappers", but they are at least manageable, controllable.
Even if I used dynamic proxies, how can I assure, that the relationship is transparently transportable? Are you sure this is not becoming EJB 1.1 RemoteEntityBeans Revival?

That's a good point. I still want to continue forward with the syncable dataset idea and see how far it can take us. As I imagine it, we can make it work without any proxies at all.
 

One more problem I see coming is transaction/atomicity/validation of updates. For JSF and other request/response systems (like my plugin) it's easy to tell, where transaction and validation should take place. When doing continous updates of small changes, when is the correct time to lock/refresh/merge - that's already difficult for a JSF application when working with multiple related entities.

I'd generally want to merge as early and as often as possible. Each merge would have three pieces: the new requested state, the state the client thinks the entity has on the server, and the state actual current state on the server. If the expected state (from the client) differs from the actual state (from the server-side entity manager), then the update is rejected and sent back to the client along with the new server state.

I'd probably avoid locking entirely. Just optimistic refresh/merge. For atomicity, we'd simply guarantee that all updates that come together in the same message will be committed or rolled back (eg. due to merge conflict) as a unit.
 

Thanks for your feedback, looking forward to some tips regarding code generation!

The documentation on Errai's code generation API is still pretty sparse, unfortunately. Probably the best place to start out would be to look at Errai code that uses errai-codegen to generate proxies. BindableProxyGenerator and JaxrsProxyGenerator are two such examples.

Cheers,
Jonathan

Regards,
Thomas

Am 28.02.2013 22:32, schrieb Jonathan Fuerth:
Hi again Thomas,

I spent this morning trying to feel my way through the use of your plugin on a simple data model (2 tables with a FK relationship) that I created yesterday. I was able to use the hibernate-tools forge plugin to generate entities, but I couldn't quite figure out how to use your scaffolding plugin to generate Errai code. Anyway, I know this wasn't really the part you were looking for input on; I'm new to Forge and I'm sure it will be easy enough to figure out when there's a getting started doc for your plugin.

So next, I turned to the Sakila project you emailed me. I got it imported into Eclipse no problem, and I deployed it to AS7 equally easily.

The first thing that struck me is that I think there are too many types being generated for each entity. By my count, there are 9 files generated for every one entity in the datamodel. Based on your README.md, I understand you need a way of controlling which parts of the object graph get sent to the client, and also which attributes are overwritten when the updates are merged back into the server. I see that a number of these files are being generated in support of these concerns.

I think my ideal situation would be to generate just 2 files per entity: a .html template and the corresponding @Templated java class. This would leave the framework responsible for tree pruning (eg. through JPA fetch rules), fine-grained merging of attributes (by diffing or transparent proxies generated at GWT rebind time) and more. I know a proxy is a proxy, but if we can keep it out of the application's src/main/java folder, I think that's a win.

I think we should keep discussing this. Sorry it took me so long to respond... I'll try to be more responsive in the future.

-Jonathan

PS: it would be nice to have these discussions on a public mailing list of some sort. What about errai-dev or a Forge dev list?

On Wed, Feb 27, 2013 at 11:00 PM, Jonathan Fuerth <fuerth@fuerth.ca> wrote:

Hi Thomas,

I still have to play more with your errai scaffolding plugin to give feedback. I created a toy data model today (as a testbed for trying out your plugin), installed the latest Forge, and installed your plugin into it. I have not yet used your plugin to scaffold anything. I expect I will have time tomorrow morning to continue that.

Until then, here are my thoughts on https://github.com/shadogray/plugin-errai/blob/master/README.md:

== Merging in updates from the client ==

I agree EntityManager.merge() is too much of a sledgehammer when it comes to accepting updates from clients. We need a way to detect updates that only affected one or two attributes–perhaps even just an attribute of a related child entity reachable from the main subject of the sync request.

I also think that for scalability reasons we have to make the client responsible for tracking the state of the object it thinks it's merging into. This is the approach I'm taking with my data sync efforts so far: when the client submits an update to the server, it reports not only the new state it's requesting, but the 'expected state' that the server should have now. Any mismatch between the expected state and the actual current state on the server means there is a potential merge conflict. By receiving both the expected state and the requested new state, the server can compute the actual field-by-field difference in the update, and decide if a real merge conflict took place. If so, it can respond to the client with the actual new state, and client code can do what it wants to resolve it (probably by presenting some sort of yes/no decision or even a merge UI to the user).

== Handling of Entity References ==

Yes, this is a major concern. Since my initial plan is to define syncable data sets using JPQL named queries, I thought it would be easiest to use the FETCH clause to define the limits of what gets synced and what stays behind (lazy fetch == don't sync to client).

Since then, the EntityGraph API has found its way into JPA 2.1. As far as I can tell, this is pretty much purpose-built to solve this problem without the need for wrapper DTOs. We could build Errai's Data Sync features against this today; the only downside is that it's going to take a while before we can count on JPA 2.1 APIs being available on the server side.

== Short and Char as ID types ==

Errai JPA does support all numeric types for IDs, but I purposely stopped short of implementing ID Generators for byte, short, and char. I'm happy to add these ID Generators if you've got a use case for them.

Thanks for your patience!

Jonathan