best way to hide ofy() from the dao?

69 views
Skip to first unread message

tfannon

unread,
Jan 17, 2011, 8:20:58 PM1/17/11
to objectify...@googlegroups.com
I decided that I don't want all my classes to call methods on ofy() directly.  I want them to go through my dao helpers.   Since java won't let me hide the method of the base class DaoBase,  can anyone suggest another way of doing it?

Thanks,
tf

Jeff Schnitzer

unread,
Jan 17, 2011, 9:09:20 PM1/17/11
to objectify...@googlegroups.com
Just copy/paste the code for DAOBase and change it as you like.
DAOBase is really just there as an example... it's only a couple lines
of code. No magic.

Jeff

Message has been deleted
Message has been deleted

Ryan Mehregan

unread,
Jan 17, 2011, 9:59:02 PM1/17/11
to objectify-appengine
You can create a wrapper that encapsulates objectify specific code.

here is an example

Step1- wrap objectify API
http://code.google.com/p/listwidget/source/browse/trunk/src/main/java/com/listwidget/server/service/ObjectifyDao.java

Step2- use it :
http://code.google.com/p/listwidget/source/browse/trunk/src/main/java/com/listwidget/server/service/ItemListDao.java

http://code.google.com/p/listwidget/source/browse/trunk/src/main/java#java%2Fcom%2Flistwidget%2Fserver%2Fservice
http://code.google.com/p/listwidget/

if you want to wrap CRUD operation it is simple.
however as Objectify grows, it does not make sense to wrap Objectify,
because Objectify itself is a wrapper around low level Datastore API.
ask yourself, do you need to wrap Hibernate code for example? no.

it is best to declare an interface that specifies all the DataAccess
operations.

then have different implementation of this interface for specific
persistence mechanism.

public interface EmployeeDAO{
List<Employee> findAllEmployees();
Employee findEmployeeById(Long id);

}

public class EmployeeDAOImplObjectify implements EmployeeDAO {
//objectify specific code here
Employee findEmployeeById(Long id){
//method containing the implementation

}
}

public class AccountDAOImplObjectify implements AccountDAO {
//objectify specific code here

or to take it to the very extreme,
we can have dozens of implementation for Employee DAO interface,
for different underlying persistence mechanisms
(Relational vs Non-Relational, for different vendors, mapping
frameworks)
in the code below, the term Repository is used in place of DAO, (it is
part of Spring lingo)

//EmployeeDAO
public interface EmployeeRepository {

List<Employee> findAllEmployees();
Employee findEmployeeById(Long id);
....

}

this is a bit extreme, but
// marker interfaces for Google App Engine BigTable Datastore
public interface GAEDataStoreRepository {}
public interface ObjectifyRepository extends GAEDataStoreRepository{}
public interface TwigPersistRepository extends
GAEDataStoreRepository{}

//marker interfaces for SQL RDBMS
public interface SQLRepository{}
public interface OracleRepository extends SQLRepository{}
public interface HibernateRepository extends SQLRepository{}

now in package:
com.project.dao.objectify.employee

public class ObjectifyEmployeeRepository implements
EmployeeRepository, ObjectifyRepository{

///here you put all the concrete Objectify specific API. ofy()

}

public class ObjectifyAccountRepository implements AccountRepository,
ObjectifyRepository{
//implementation

}

if you later decided to use an RDBMS, you can write

public class HibernateEmployeeRepository implements
EmployeeRepository, HibernateRepository{}
public class HibernateAccountRepository implements AccountRepository,
HibernateRepository{}

the idea is that rest of the application interacts with
EmployeeRepository(EmployeeDAO API),
rather than interacting with the classes that contains the low level
implementation details.

it is the Object Oriented best practice of programming to the
interfaces, since an interface defines a contract that clients of this
API can rely on.
(clients for example web-tier/GUI)

from their point of view it does not matter whether the data is stored
in a local file, local database, or somewhere on the cloud.
they know if they call findEmployeeById, passing it an ID, they will
get an Employee object, and cant care less where or how this Employee
Object was retrieved.
as a result you can swap underlying persistence mechanism without
affecting the rest of your application.

I therefore suggest you define a DAO interface for each of your
entities, and then implement this interface,
putting all the objectify specific code in this implementation.

You can then use the interface in other part of your app (eg. web
tier) instead of the concrete implementation class, what this means
is that other part of your app "depend" on the interface not
implementation,
which contributes to loose coupling, and clean separation of
responsibilities.

Didier Durand

unread,
Jan 18, 2011, 12:36:47 AM1/18/11
to objectify-appengine
Hi,

I would also suggest to use inheritance in addition to just
interfaces, especially when you're in the realm of implementation for
Objectify.

I personally have a Class OfyObject from which all my objects inherit:
this class contains fields that i want in each object creation_date,
last_update, version (for transactional consistency), etc. It's code
that you write only once and that you enjoy then in each class. Those
fields are very useful for statistical and debugging purposes.

To maintain them, I use @PrePersist hooks in OfyObject: I have then
theses fields managed fully transparently from the application.

Additional point: you have to register your classes with Objectify
each time you want to use Ofy. Depending on your application, it's
possible to "hide" this registration in the static anonymous block
"static {}" or in the anonymous constructor block of your class or
even of OfyObject. -> less code and less possibility for errors.

So, although I very much agree with the rules mentionned by Ryan in
his interesting post, I would also suggest to think about inheritance,
not only interfaces.

regards

didier

On Jan 18, 3:59 am, Ryan Mehregan <ryan...@gmail.com> wrote:
> You can create a wrapper that encapsulates objectify specific code.
>
> here is an example
>
> Step1- wrap objectify APIhttp://code.google.com/p/listwidget/source/browse/trunk/src/main/java...
>
> Step2- use it :http://code.google.com/p/listwidget/source/browse/trunk/src/main/java...
>
> http://code.google.com/p/listwidget/source/browse/trunk/src/main/java...http://code.google.com/p/listwidget/

zixzigma

unread,
Jan 19, 2011, 11:18:52 PM1/19/11
to objectify-appengine
Hello Didier,
have you worked with GWT 2.1 RequestFactory ? (EntityProxy)
I believe Inheritance is not supported.
I was wondering how you get around that problem ?

Didier Durand

unread,
Jan 20, 2011, 12:30:51 AM1/20/11
to objectify-appengine
Hi,

I do not yet use GWT 2.1.

I don't plan to use RequestFactory because of the kind of limitation
that you mention: it ties front-end and back-end to tightly, i.e, GWT
compiler to JS needs then to understand too much of the back-end
object hierarchy.

When I say too much, I mean that it must be able to import and compile
quite a lot of source code from back-end. The current limitations of
GWT compiler in terms of JRE emulation (limited classes and methods
supported) makes this impossible: it just can't compile fancy code
from the back-end.

So, I do 2 things: (1) use dumb RPC/front-end objects with limited
inheritance and al. that I instantiate automatically (reflection) from
their smarter back-end counterpart and (2) have my own (limited)
object factory on the front-end to handle single copy, caching, etc...
functions provided by RequestFactory in my own structure.

It's more proprietary code on the front-end but that the best way I
found to leverage Objectify and other GAE functions with maximum
efficiency in regard to current limitation of GWT compiler and
architecture.

regards

didier

Peter Knego

unread,
Jan 20, 2011, 3:42:08 AM1/20/11
to objectify...@googlegroups.com
We've been using GWT 2.1 RequestFactory and the whole point is to
separate front-end and back-end classes.
This is done vie EntityProxy:
http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.html#proxies

So you can have whatever classes you want on the backend and then
expose only properties you want through a proxy. This is the biggest
advantage over GWT-RPC.

The drawback is that you need to write all the proxies by hand and
keep them manually in sync - there is no common class/interface
between client and server. So if you change some Entity classes on
server you have to manually inspect the proxy and change it too.

Also, RequestFactory does not support serializing Maps, which we
needed badly for dynamic properties. So we had to revert back to
GWT-RPC.

Peter

Didier Durand

unread,
Jan 20, 2011, 9:55:36 AM1/20/11
to objectify-appengine
Hi Peter,

Very interesting complements!

thanks a lot

didier

On Jan 20, 9:42 am, Peter Knego <pe...@knego.net> wrote:
> We've been using GWT 2.1 RequestFactory and the whole point is to
> separate front-end and back-end classes.
> This is done vie EntityProxy:http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.h...
>
> So you can have whatever classes you want on the backend and then
> expose only properties you want through a proxy. This is the biggest
> advantage over GWT-RPC.
>
> The drawback is that you need to write all the proxies by hand and
> keep them manually in sync - there is no common class/interface
> between client and server. So if you change some Entity classes on
> server you have to manually inspect the proxy and change it too.
>
> Also, RequestFactory does not support serializing Maps, which we
> needed badly for dynamic properties. So we had to revert back to
> GWT-RPC.
>
> Peter
>
Reply all
Reply to author
Forward
0 new messages