requestfactory and findEntity method in GWT - gwt

I am trying to use RequestFactory. My ORM provider is JPA. I have a method to retrieve a list of entity called findAll(). When the user requests for a list of entities, findAll is called. Find all executes a query against database and returns a list of entities. However, when requestFactory is asked to send this list back to the user, requestfactory calls findEntity() for each entity in the list.
My question is: is there any way I can instruct request factory to not call find entity for each item in the list?

This is likely from SimpleRequestProcessor.createReturnOperations() determining whether or not your domain objects are live, in order to send the appropriate Delete, Persist, or Update WriteOperation value. The default implementation of ServiceLayer.isLive() calls the finder method to determine if the object can be re-loaded. You can provide your own subclass of ServiceLayerDecorator that overrides the isLive() method by subclassing RequestFactoryServlet and calling the multi-arg super-constructor.

Related

Should a GWT RequestFactory Locator method expect a passed-in JPA entity to be attached or detached?

Right now I have to call JPA merge() at the end of my service method to persist changes. I'm doing this because our servlets do not start a transaction before the Locator.find() runs. They start them later in the service method.
I know that RequestFactory uses my Locator find() and updates the object based on what the client sent to the server, so I was just wondering if maybe that object should be an attached object and therefore allow JPA to handle the changes "naturally" rather than explicitly call merge().
Or perhaps this just depends on the situation?
I don't know JPA much, but I confirm that you SHOULD scope your transactions to your service methods: a RequestContext is a batch of requests that can each succeed or fail independently, putting them all in a single transactions would violates that principle. There are also cases where your Localor#find can be called, changes applied to the entity, but then the entity is never passed to any service method: you wouldn't want the changes to be persisted in this case.

How to get a detached object from JPA

In my application I need most objects fetched in detached mode (fetched with the find API).
I'm wondering if there is a way to ask a detached object from the JPA provider and save the extra call to detach() API.
In additional I would expect the object created in such mode to be less expensive since the JPA provider doesn't need to add it to the entity manager context.
Is there a way to achieve this with JPA APIs?
Is there a way to achieve such functionality with query results?
Specifically I'm using Eclipse Link so if there is a specific way to do it with this implementation it will be helpful as well.
You can fetch a detached entity without an extra call to detach() if you fetch it outside a transaction. If you are not using container-managed transactions, it's trivial, simply do not start a transaction.
If you are using CMT, you have to make sure the requesting object is not a transaction-enabled EJB:
if in an EJB, suspend the transaction by annotating the appropriate method with:#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED),
or
call the EntityManager from a POJO. You dont have to call it directly, it only impotrant that the query result will end in a non-EJB object.
AFAIK, there is no performance gain to be expected, since the query result will always be put in the current persistence context, however shortlived it may be.
EDIT: There is another possibility to get detached objects which does not depend on transaction demarcations: JPA constructor expressions:
List<DTO> dtos = em.createQuery("SELECT NEW com.example.DTO( o.title, o.version) FROM Entity o").getResultList();
The constructed type must have a constructor with all the relevant attributes. The objects in the list, entities or not, will always be created detached. However there is a small overhead of instantiating a new object.

com.google.web.bindery.requestfactory.shared.Locator.getVersion() - What is this method used for?

I'm writing my first GWT-Application and need your advice. I have no problems implementing a locator for database entities where I can reuse the version-column used for optimistic locking by hibernate, but one of my entities represents a ldap-Object. Can you tell me what the method getVersion() of the Locator is used for and how I can implement this method for my ldap-Object? I will do read and write ldap objects.
From GWT documentation, getVersion method is
Used by RequestFactory to infer if an entity has changed. The backing store (JDO, JPA, etc.) is responsible for updating the version each time the object is persisted, and RequestFactory calls getVersion() to learn of changes. This information is used in two places. First, the RequestFactoryServlet sends an UPDATE event to the client if an entity changes as a result of the method invocation on the server, for example, when a call to persist an editable entity results in an updated version on the server. Second, the client maintains a version cache of recently seen entities. Whenever it sees an entity whose version has changed, it fires UPDATE events on the event bus so that listeners can update the view.
Since many persistence frameworks offer generic find/get/query methods, it's also possible to create a generic Locator class and specify it in the #ProxyFor annotation for each entity type. To do this, all your entities can extend a base class that provides getId() and getVersion(). Alternatively, the generic Locator can use reflection to call getId() and getVersion() when needed.
Not sure if you're looking for anything else in addition to this.
I have the same problem. My first thought was to use the Attribute modifyTimestamp and createTimestamp. But there is still a functional gap:
The smallest unit of These timestamps is seconds so a Change in the same second can not be detected. Another solution would be to use a kind of checksum over all attributes of the ldap object. Not very nice..

Is is possible to attach EntityProxy to another RequestContext ? And should I?

I have a little form that edits my entity. I create that entity using one instance of RequestContext and then in handler of "save" button I'm trying to persist it using another instance of RequestContext.
Attempt to persist fails with expected exception: java.lang.IllegalArgumentException: Attempting to edit an EntityProxy previously edited by another RequestContext
The questions are:
Is is possible to attach EntityProxy to another RequestContext ?
Is it right thing to do ? Or I should reuse one RequestContext saving it
as property of my class ?
Reuse the existing one. If you need a new one, merge them. But it really doesn't make sense to make a new one. Here's why:
When you make a RF call to the server, it goes through several steps, as it is geared mostly toward how to read and persist entities, and the various value properties they work with.
Create or retrieve any of the instances to be dealt with
Apply setters to these instances, new or existing, and validate them
Run the service invocations, either as methods invoked on the entities, static calls, or service calls.
These three steps are done in this order to ensure that the object modified and then passed to a service call makes sense when it gets there. Future calls (i.e. other requests) then probably do not need to make those same changes to the same entities, and if they do, then they need to make the changes themselves.
A given RequestContext consists of all of these things then. If you had two requests, and one represented the setters to be called (the edits from the form) and the other the service request, firing one means only calling the setters, but not the service call to save it, while firing the other means only call save without the service call.
After an EntityProxy has been marked as being edited by one request context, attempting to use it in another one is almost certainly an error, so the exception you are seeing is thrown. Use the existing one, or use RequestContext.append if needed to switch to a new RequestContext type to actually run the save operation.
RequestFactory isn't RPC - your objects aren't just Java Beans, but are proxies (either EntityProxy or ValueProxy) of some server object, and requests are used to manipulate them asynchronously.

Does Gwt 2.1 Entity Proxy support transparent call to lazy loaded entity relations?

Well, I have read the document about Entity Proxy http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.html . As far as I understood Entity Proxy does not support transparently calling of lazy loaded entity relations. Such as, I have Employee entity, and this entity has supervisor field whose type is Employee, and this field fetch type is lazy.. When I have queried an employee, can I call its getSupervisor method at GWT layer?.. What I expect EmployeeProxy calls transparently getSupervisor method of Employee entity on the server.. Is this the case?.
No, just as you mention it doesn't support lazy loading. It would also be difficult, because while you want to do a getSupervisor(), which would return the data, in practice this would mean GWT performs an asynchronous call, and needs a receiver. Technically, it might be be possible to implement something like lazy loading, but due to the asynchrony it would never be possible to simple do a getSupervisor().
There is the gilead project that might do what you intend.