Re: GWT 2.1.1 RequestFactory Strange Exception
I cannot understand how I could persist a domain object, using the new service layer. Because when I call pm.makePersistent(arg); I need to have access to the instance of the domain object that is going to be stored. Before, I could just write pm.makePersistent(this); according to the example, referring to the domain object. But know, where I call the same method through a service, how can I have access to the domain object. Should I call Locator, and how exactly could I do that? -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
SL vs DAL, one example of how they are different is that: let's say we have a DAO for accessing a Customer entity a DAO for accessing Account entity a DAO for accessing History/Trend entity // maybe not a good example, but just three separate entities a Service(object) living in a ServiceLayer, needs to access these three entities, analyze them and based on a current condition, apply a policy, and then notify the interested parties. the Logic for sending Notification is in another Object. the Logic for Accessing/Finding those entities are in another object. our Service(object) responsibility is to perform some operation, with the help of those other objects. (through collaboration). in this case, our Service is not just a basic CRUD. to complicate things further, (in a real world scenario), not all of the data might come from same DataStore, one using a local DataStore, one a WebService to retrieve realtime data, so when going beyond basic CRUD, the need for a Separate(isolated) ServiceLayer and DataAccessLayer, becomes more obvious. -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
Thank you so much for your feedback on this. I am going to experiment more, using your guidelines. as for the need for additional layer, a valid use case could be this: lets say you are going to deploy your app on GAE. for the persistence, there are several options: - JDO/JPA - DataStore LowLevel APIs - Objectify, Twig Persist many of these technologies are new and subject to (rapid) change, it is a good idea to use interfaces to declare our DataAccess "contract" without exposing infrastructure related detail that is specific to each of those technologies. if one has 20 domain objects(entities), and for each entity, certain requests/methods : findX, findXInRange, findByX, it can get out of hand quickly. it would be very difficult to swap one persistence technology for another, sometime down the road. the idea is, - loose coupling - easily swapping infrastructure specific code, without affecting other part of system (easy refactoring, testing,) - clearly defined contracts in the form of interfaces, when you look at an interface you can see what is expected of this DAO, rather than going through hundreds of lines of codes, some of which scattered with try/catch/finally blocks (i am exaggerating a bit, IDEs can provide a quick overview) having said that, if one is working on a project that uses a legacy database, a database that's been in that environment for years, where DBAs have developed custom scripts, and its been used in day to day operation of that business/organization for many years, and there are policies within that business/organization to continue using that database in the future, I agree, using abstractions might be an overkill. As with most things, I believe it all depends on the requirements/ constraints. -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
RequestFactory sends diffs on the wire (client-to-server), so how would your Service Object (as you call it) would receive a "complete" domain object if the diff isn't applied to an object retrieved from the database/datastore? Things are a bit more "blury" than "service layer on top of data access layer". If you want to name things, RequestFactoryServlet is part of your service layer, and delegates a few (a very few) things to DAOs (Locator, or static findXxx methods), and all the "business logic" to other pieces (services, as referenced in @Service/@ServiceName, or instance methods on your domain objects) (as for the SL vs. DAL, I never bought that; the few times I used that "strict" approach, one was almost useless; JPA/JDO/whatever *are* the DAL, you hardly need an additional layer, and each layer removes some ways of optimizing things, notably database/datastore requests; but that's another debate) -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
from your explanation I get the feeling that Locators are DAOs, is this correct ? placing calls like these: EntityManager#find(clazz,id) inside a Locator, means Locator is now responsible for accessing datastore to perform actions. it also means that our DAOs are somehow directly coupled with RequestFactoryServlet. A common design approach is to have a Service Layer and a DataAccessLayer, that communicate through interfaces. when the request comes from the client, it gets routed to the Service object responsible for performing a business logic to fulfill clients request. In doing so, the Service object, may interact with "a number of" DAOs, to perform the task. and if Required, this "Service object" returns the data that has to be given to the client. in GWT 2.1.1 RequestFactory Servlet, ServiceLocator can be used to locate the Service Object responsible for fulfilling client request. However, how the ServiceObject communicates with server-side DAO to get its data is the ServiceObject concern, not the RequestFactoryServlet. In otherwords, our Service Object itself knows how to locate DAOs, therefore why do we need this Locator for our EntityObjects ? On Dec 22, 2:19 am, Thomas Broyer wrote: > Well, as always, it depends what you need and what you can do. > > If you can implement a single Locator class that works for all your > entities, then go with it; and otherwise make one for each entity. > For instance, if you have a base class for your entities that provides an ID > and version, then you can easily cast any entity to that class to implement > getId and getVersion, and you probably can implement getIdType by returning > a fixed type. > You can clazz.newInstance() in the create() or use > PersistenceManager#newInstace with JDO. > And you can easily "find" using the Class and ID with JPA using > EntityManager#find(clazz,id), or with JDO using > PersistenceManager#getObjectById(clazz,id). -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
I use the same pattern explained here with JPA/Spring for the Entity Locator http://groups.google.com/group/google-web-toolkit/browse_thread/thread/20ea2aea53aa29d3/687ff2df944c483c public class MyDataLocator extends Locator { private MyRepository getRepository() { HttpServletRequest request = RequestFactoryServlet.getThreadLocalRequest(); ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext()); MyRepository repository = context.getBean(MyRepository.class); return repository; } @Override public MyData create(Class clazz) { MyRepository repository = getRepository(); repository.persist(new MyData()); *return null;* } @Override public MyData find(Class clazz, Long id) { MyRepository myRepository = getRepository(); MyData entity = myRepository.findByPrimaryKey(id); return entity; } @Override public Class getDomainType() { return MyData.class; } @Override public Long getId(MyData domainObject) { return domainObject.getId(); } @Override public Class getIdType() { return Long.class; } @Override public Long getVersion(MyData domainObject) { return domainObject.getVersion(); } @Override public boolean isLive(MyData domainObject) { return super.isLive(domainObject); } } MyRepository is a Spring Repository with an injected EntityManager. The only problem I still have is, that entityManager.persist(entity) returns void. And returning the created instance is a bad idea, since the primary key ID is not yet generated. *Do we really have to return the created object or may we return null*? The only way out I see is to make another call to the repository and read the newly generated object, when using JPA. By the way, Repository must start and commit the DB Transaction. Daniel -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
On Wednesday, December 22, 2010 12:59:16 AM UTC+1, zixzigma wrote: > > Thank you, it all makes sense now. > > However what you described is how GWT RF uses those details > to do its magic behind the scenes. > > I am not clear what our responsibility is then ? > Provide the "right" values so RF can "do its magic" ? What should go inside the Locator ? > > From the code I posted, > http://paste.pocoo.org/show/308153/ > > I don't know what I should put in there. > > I have a ServiceLocator ( one per application), > that locates Services. those Services are independent from GWT RF, > they can connect to persistent stores, do whatever they want. > and return a retult/perform action that is expected by RequestContext. > > and what you described for Locators > @ProxyFor(value=PersonEntity, locator=EntityLocator) > public interface PersonProxy { > > > from your explanation I understood why Locator is important, > but what should we/the developers put in it ? > and do we need one per Entity or one per Application ? Well, as always, it depends what you need and what you can do. If you can implement a single Locator class that works for all your entities, then go with it; and otherwise make one for each entity. For instance, if you have a base class for your entities that provides an ID and version, then you can easily cast any entity to that class to implement getId and getVersion, and you probably can implement getIdType by returning a fixed type. You can clazz.newInstance() in the create() or use PersistenceManager#newInstace with JDO. And you can easily "find" using the Class and ID with JPA using EntityManager#find(clazz,id), or with JDO using PersistenceManager#getObjectById(clazz,id). Basically, you could very well have only one Locator class per "id type". Oh, and something to keep in mind: the Locator and *your services* instances (not the ServiceLocator instances though) are cached aggressively and reused for all subsequent requests, so make sure they are thread-safe ! (have a look at the ServiceLayerCache class to see all "memoized" methods) -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
Thank you, it all makes sense now. However what you described is how GWT RF uses those details to do its magic behind the scenes. I am not clear what our responsibility is then ? What should go inside the Locator ? >From the code I posted, http://paste.pocoo.org/show/308153/ I don't know what I should put in there. I have a ServiceLocator ( one per application), that locates Services. those Services are independent from GWT RF, they can connect to persistent stores, do whatever they want. and return a retult/perform action that is expected by RequestContext. and what you described for Locators @ProxyFor(value=PersonEntity, locator=EntityLocator) public interface PersonProxy { from your explanation I understood why Locator is important, but what should we/the developers put in it ? and do we need one per Entity or one per Application ? sorry I repeated myself, I am still a bit confused :" ) -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
The getId method is used generate a "stable id" that's transmitted to the client so that the object can be identified when it's later updated, and the find() method (see below) can be called with the appropriate identifier. You don't have to define a getId() in your EntityProxy, and if you do, it'll be resolved as a property, not by calling getId. The getVersion method is used to send to the client the version of the object it "knows about", so that when it send it back to the the server (generally with changes), the server can quickly bail if it knows that the server-side version is different (i.e. getVersion is called to send the version to the client, and also at the very beginning of the server-side processing to check that the version known by the client is not out-dated, i.e. an optimistic lock). It's also used, just before returning to the client, to detect if a given object has been changed by the service methods (RF then generates the appropriate payload in the response so that an UPDATE event is dispatched on the client-side) The find method is called to update the domain entity when you send one from the client to the server (RF will actually only send deltas of your changes, not the whole object, that's (one of) the point(s) of RF), e.g. to pass it to a persist() service method. The create method is called when you send to the server an object that you RequestContext#create()-d on the client-side. The isLive method is called for each object sent over the wire on a given request (from client to server and from server to client) to possibly generate the payload in the response so that a DELETE event is dispatched client-side. Finally, getDomainType is useless, it's never called. -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
Thank you guys for the tips. I got it to work! Thank you very much ! I noticed a VERY STRANGE behaviour. following your suggestion, I declared: @ProxyFor(MyPersonEntity, EntityLocator) PersonProxy @Service(MyPersonService, MyServiceLocator) PersonService I noticed when methods in PersonService are declared "static", ServiceLocator is "bypassed", and is NEVER used by RequestFactory to look up "PersonService" RF directly goes to PersonService. This was strange, because what is the point of ServiceLocator then, if it is going to be bypassed ? to force RF to go through ServiceLocator, you have to remove "static" from your Service methods. This is where things get even more STRANGE: if I do not define a Locator, I get exceptions complaining PersonRequest did not pass validation. however if I define a Locator (by extending Locator Interface) I then have to implement bunch of methods: find/create/getId/ getVersion I return NULL from all methods, and it still works ! why is that? and why we are forced to define a Locator, if we already have a Service defined ? my Locator does nothing ! you can see the code here: http://paste.pocoo.org/show/308153/ from the debug statements, I see these methods being invoked: [1022][INFO ][main][EntityLocator::22] - #EntityLocator constructor called [1022][INFO ][main][EntityLocator:getId:45] - # get Id # [1023][INFO ][main][EntityLocator:getVersion:57] - ### get Version ### however, I returned null for all of them, still the client receives the correct Id/Version as I set in my PersonService#find method. could someone from GWT Team please explain. I am beginning to love the new RequestFactory, Thank You ! -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
in RequestFactory 2.1.1 documentations (source code), there are many references to Domain and Domain Environment, I am unclear what is meant by Domain Environment. is it on the server side where RequestFactory work stops and our work begins ? it helps if the documentaton clarify the vocabulary, Locator, Service, ServiceLocator, Domain, Domain Environment, ServiceLayer is ServiceLayer a DAO layer or a true Service Layer. ServiceLayer vs Domain Environment ? what is the distinction between the two ? -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
On Dec 21, 6:25 am, Matt Moriarity wrote: > But in order to get your static service methods (besides just the find > method), you need a ServiceLocator for your service: > do all these methods have to be static ? I thought the idea behind 2.1.1 was to get rid of static ? I am a bit confused on what is meant by the term "service" methods. Normally we have a "Service Layer", and a "Data Access Layer" Data Access Layer (all the DAOs), responsible for communicating with persistent stores to find objects of a "given type" findCustomerById, ByEmail, AllCustomers, AllCustomersWithCriteriaX all of this goes into CustomerDAO then you need a Service Layer, that uses many of these DAOs to satisfy a use case. PersonService, might use PersonDAO, AccountDAO, and more ..., performs a business logic on them and take some action. in RequestFactory 2.1.1, do you think the ServiceLayer and ServiceLocator is just for locating the DAOs or the Service objects as I described ? (because in RequestFactory 2.1 even the DataAccess (DAOs) where inside Entity class. to achieve the complete isolation we need a ServiceLayer + DataAccessLayer on top of our Entities. with RF 2.1.1, can we specify just the Service method in GWT, and leaving the job of dealing with DAOS to the Service object ? > @ProxyFor(value = Person.class, locator = PersonLocator.class) > > then having a PersonLocator which implements Locator would fix this > for you. > > @Service(value = PersonService.class, locator = MyServiceLocator.class) > > I'm not sure if the locator for the service is necessary if it has a default > constructor. We use Spring, so we have a service locator that just pulls the > bean out of spring. I am planning to use it with Spring too. in your case (spring), you need all 4 attributes ? on PersonProxy we use @ProxyFor(EntityObject, EntityLocator) on PersonService we use @Service(ServiceObject, ServiceObjectLocator) so the EntityLocator is the DAO ? and ServiceLocator queries spring context to find the Service method to handle the EntityLocator ? yet, all of these methods have to be static ? Thank You -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
@ProxyFor(value = Person.class, locator = PersonLocator.class) then having a PersonLocator which implements Locator would fix this for you. But in order to get your static service methods (besides just the find method), you need a ServiceLocator for your service: @Service(value = PersonService.class, locator = MyServiceLocator.class) I'm not sure if the locator for the service is necessary if it has a default constructor. We use Spring, so we have a service locator that just pulls the bean out of spring. -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
>From the RequestFactory documentation: Four special methods are required on all entities as they are used by the RequestFactory servlet: A no-arg constructor. This may be the implicit default constructor. 1. id_type getId() -- IDs can be String or Long 2. static entity_type findEntity(id_type id) 3. Integer getVersion() You could argue that this means that you cannot easily make a separate service and I believe you would be right. The only way to do this, I believe, is to create a Locator for each proxy. I asked the same question a couple of days ago. See http://groups.google.com/group/google-web-toolkit/browse_thread/thread/c929fb1d4239f7e0 -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
I realized I was using the 2.1 style to create my RequestFactory I came across this, while digging into code: * ServiceLayer serviceLayer = ServiceLayer.create(); * SimpleRequestProcessor processor = new SimpleRequestProcessor(serviceLayer); * EventBus eventBus = new SimpleEventBus(); * MyRequestFactory f = RequestFactoryMagic.create(MyRequestFactory.class); * f.initialize(eventBus, new InProcessRequestTransport(processor)); now I am going to experiment (in test mode) with this, see if I am correct in my guess. -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: GWT 2.1.1 RequestFactory Strange Exception
tracked down the problem, it has to do with validation: " RequestFactoryInterfaceValidator" this validation fails: RequestFactoryInterfaceValidator v = new RequestFactoryInterfaceValidator( logger, new RequestFactoryInterfaceValidator. ClassLoaderLoader(PersonRequest.class.getClassLoader())); v.validateRequestContext(PersonRequest.class.getName()); assertFalse(v.isPoisoned()); as stated in previous post, the source code can be found here: http://paste.pocoo.org/show/307617/ I tried different combination of classes on @Service Annotation (also locator attribute), different combination of static/non-static. basically trial and error, checked it with expenses sample, and RF wiki, still can't get it to work. I don't know what I am doing wrong, please Help : ( -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
GWT 2.1.1 RequestFactory Strange Exception
I am using GWT 2.1.1 new RequestFactory Service layer, but I keep getting exceptions instructing me to declare my Service methods "static" and in my domain(entity) classes. (instead of a separate service layer [the point of 2.1.1]) the formatted code for easy reading can be find here http://paste.pocoo.org/show/307617/ when I move the findPerson method to the Person entity class, and declare it static, it works, but I don't know why the new @Service doesn't work. in debug statements, I also verified that the version I am using is in fact 2.1.1 Would be grateful if you can provide some tips or comments on how I can make my code work. Thank You -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.