2 Replies Latest reply on Jul 4, 2012 2:25 AM by bfluri

    Marshalling @Entity classes

    bfluri

      We decided to use Errai in our project because

      • We can use @Entity classes and their validation on the server and on the client.
      • Errai provides CDI Event on the client side, so we get push notifications for free, that is great!

       

      Both reasons allow us to highly integrate the client with the server.

       

      Besides bean validation on the client side, the main goal of using @Entity classes (entities) on both sides was to get rid of DTOs and their instance generation. So, naively, we assumed that we can just send entities to the client without doing any additional serialization work. Naively, because we thought Errai helps us in transparently sending entities from the client to the server. After a while, when our domain model was extended by one-to-many relationships, we noticed that we have to detach the entities from the entity manager first and then clear out any persistent set, bag, etc. before sending the entities to the client. Otherwise, the Errai marshaller classes reported LazyInitializationExceptions. From an ORM point-of-view we understand why we have to that. However, are these steps really necessary when using Errai as the transparent communication framework? Doesn't or shouldn't Errai provide this work? We didn't find any helpful information for our question - neither in the Errai documentation nor in the web. Are we doing it as intended?

       

      I appreciate any advice.

        • 1. Re: Marshalling @Entity classes
          jfuerth

          Yes, this ability to share entity code between client and server is a big advantage we're trying to achieve with Errai. Glad to hear it's (nearly) working out for your project.

           

          About your issue with lazy loading and Errai marshalling not playing well together, I acknowledge that this is a weak area, and it's one that we want to address in Errai 2.1. I have a few comments and suggestions:

           

          1. I don't think there's any safe & predictable way of magically detaching entities and ignoring their lazily initialized data. After all, JPA2 even allows individual fields to be lazy-loaded. I think the best (least demand on the programmer; most declarative approach) we could do is provide an annotation you can apply to entity fields which makes them invisible to Errai Marshalling: something like @DoNotMarshal or @ErraiTransient. Before handing over an entity graph to Errai, you would be responsible for ensuring that each property of every object in the graph is either populated or marked "do not marshal this."

           

          Does this sound like a happy medium for your use case?

           

          2. I am currently working (in the 2.1 branch) on a client-side JPA2 implementation for Errai. Presently, it uses localStorage in the browser for storing and retrieving entity instances. Presently, retrieval can only be done by entity ID or by named queries. If you can think of a use case for this in your app (eg. offline support or caching hot data for speeding up page reloads) then I'd really appreciate some feedback on this feature.

           

          3. Building on point #2, we will soon be starting work on a data synchronization facility that builds on both client-side and server-side JPA. The basic plan is that you would choose one or more named queries, fill in the query parameters, then tell the data synchronization API "keep the results of this data set in sync between the server and the client(s)." The datasync system would use Errai's push messaging system to publish changes in the data set between client(s) and server. Offline support will exist, and there will be a user-provided callback for managing conflicts in case the same data was updated independently in multiple places.

           

          We think this "syncable dataset" idea has a lot of promise, but since we're still in the design phase, it's unfortunately not going to help you in your present predicament.

           

          -Jonathan

          • 2. Re: Marshalling @Entity classes
            bfluri

            Thanks a lot for your quick and detailed answer, Jonathan!

             

            @1: These annotation suggestions are definitely reasonable, but they won't solve our issues. At the moment, we distinghuish between one-to-many relationships as follows

            • If the collection is empty, and lazyly fetched respectively, we convert it to an empty collection. So the collection is returned but empty.
            • If the collection has items, we start the detaching process for each item.

            We can influence the state of the fields by configuring our queries (fetch join). So, we do not simply ignore certain fields per default, but treat them according to their state. However, @DoNotMarshal is useful because we may have fields that never should go to the client.

             

            @2: In a less generic way, that's exactly what we are doing at the moment. We have tables of entities that show some basic properties of them. If you click on a row, it re-fetches the entity by ID and shows it in an editor with all n-ary relationships.

             

            @3: That sounds very promising indeed. I'm looking forward to any future releases .

             

            --Beat