Re: GWT 2.1.1 RequestFactory Strange Exception

2010-12-26 Thread giannisdag
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

2010-12-23 Thread zixzigma
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

2010-12-23 Thread zixzigma
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

2010-12-23 Thread Thomas Broyer
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

2010-12-23 Thread zixzigma

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

2010-12-22 Thread dagerber
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

2010-12-22 Thread Thomas Broyer


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

2010-12-21 Thread zixzigma
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

2010-12-21 Thread Thomas Broyer
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

2010-12-21 Thread zixzigma
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

2010-12-21 Thread zixzigma
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

2010-12-21 Thread zixzigma

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

2010-12-21 Thread Matt Moriarity
@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

2010-12-21 Thread Henrik Schmidt
>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

2010-12-21 Thread zixzigma
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

2010-12-20 Thread zixzigma
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

2010-12-20 Thread zixzigma
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.