Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Remote Application Platform (RAP) » Small talk about RAP and using a persistence layer (e.g. Hibernate)
Small talk about RAP and using a persistence layer (e.g. Hibernate) [message #131691] Thu, 07 May 2009 09:05 Go to next message
Eclipse UserFriend
Originally posted by: benjamin.wolff.web.de

hi!


i'm currently struggling with some very basic design problems when planning my new RAP app.
however using a domain object model (dom) which represents the business objects is a
very common approach i think. also it is very usual to use a relational database as the
persistent storage for such an application.
in some first projects, which i implemented in RAP, i used direct JDBC code (sql statements, session
and transaction managing with code etc.). this time i want to make it 'right'. the first step
was to use hibernate for object relational mapping and the machnisms to access the database (no
more direct SQL etc.). so the mapping of the dom objects to the database wasn't a problem at all,
but here are the problems arising. i want to work with JFace viewers and the proper content provider etc.
the fact that RAP is an ajax application, it seems to be very problematic to work with hibernates lazy
loading because i don't really now where and when to handle the sessions. in hibernate each and every
database access has to be in a transaction, every transaction is within a session, a commit or
rollback of this transaction also closes the session.
so the question is how to implement a proper session behaviour for access to the database WITHOUT
polluting the code of the actual RAP application with any session code?!
of course i want to try to seperate the persistence, data-access, controller and presentation layer
as good and as much as possible. the controller and presentation layer is actually the rap application.
the DOM and the database access is of concern of the underlying tiers.
i spent the last few days reading and studying much about hibernate and even spring but i couldn't
get a proper model or concept for this issues until now... there are many discussions about the
session handling, but these are mainly based on a desktop application (no multiuser environment in a VM)
or servlet environment such as JSP. the interactive character of an ajax app (RAP) makes it more
complicated because there is to clear request -> open session -> render response -> close session -> response
behaviour. not every request needs a DB session, this would not scale very well.
also EAGER loading with hibernate isn't an option due to performance and memory issues and other problems.

long story short, i just wanted to ask about your experience and how you manage the persistence
in your rap application?!? i'd be grateful for any hints or pointer on that topic, you can just phrase
your concept in some words without getting too technical. also any ressources on this topic may be posted
here as well.

the background is, that i'm currently working on my diploma thesis, i want to implement a nice application
with RAP. i'm planning to publish my work afterwards, so any input, help and knowledge will be
available afterwards :)).


thanks!!


greetings,
ben
Re: Small talk about RAP and using a persistence layer (e.g. Hibernate) [message #131717 is a reply to message #131691] Thu, 07 May 2009 10:31 Go to previous messageGo to next message
Stefan Hansel is currently offline Stefan HanselFriend
Messages: 103
Registered: July 2009
Senior Member
Hi Benjamin,

our App uses JDO + Spring, but the fundamental problems are the same as
with Spring+ Hibernate/JPA.
Have a look for 'Integrating Spring: OpenSessionInView-Pattern in RAP' in
this newgroups for further information and links to other posts.

Actually in RAP you still have proper requests (typically button-clicks),
unfortunately they don't work with Spring out of the box, as RAP has it's
own UI-Threads and Spring heavily uses ThreadLocals to handle
request+sessionstate.
Basically in a PhaseListener (which is already called on the UI-Thread
before and after application-code handles the request) we trigger the
Spring-Initialization that they typically do in a ServletListener.

Thus we get a proper working ApplicationContext of Spring which handles
all JDO-stuff (building PersistenceManagerFactories).
Furthermore the @Transaction-annotiations are fully working and Spring
handles retrieving and releasing PersistenceManagers
(=Sessions/EntitiyManager in Hibernate/JPA) like it does in any other app.

It depends on your application / architecture how far you go with lazy
loading.
In a classic 3-tier-architecture, the view can't do any lazy-loading
anymore (Sessions are closed on leaving the transaction of a
Manager/Service-class).
Anyway - there is a pattern called 'OpenSessionInView' - which some don't
like (at least there is a lot of discussion about pro/cons) - but we do !

Coming from Swing, where our PersistenceManagers where open all the time
(thus lazy-loading working all the time), we didn't have a problem to use
the pattern in RAP as well.

One gotcha remained still: as with OpenSessionInView the session lasts as
long as the Request, lazy-loading only works in the current request.
This is kind of problematic, because on each subsequent button-click you
can't use the object anymore. I think with hibernate merging a detached
object with a new session might be easier as with JDO.

Anyway - in our app, the view is not allowed to hold references to the
entities, otherwise we'd have a lot of problems with accessing fields of
'old' detachted objects from previous request.
Instead they only hold the ID of the objects in question and to make it
easier, we have a generic proxy-object which handles this automatically.

This is also done because of memory-considerations:
It doesn't make sense, to retrieve an entity, put all values into
GUI-fields and then keep the entity in memory, until the user decides what
to do next. The memory is always filled twice (all values are stored in
the GUI fields, furthermore in the Entitiy itself).
When the view only remembers the ID of the entity, we save up to 50% of
memory per session.
Re: Small talk about RAP and using a persistence layer (e.g. Hibernate) [message #131724 is a reply to message #131717] Thu, 07 May 2009 11:30 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: benjamin.wolff.web.de

hi stefan,


thanks for the infos. i'm currently playing with the phaselisteners you
demontrated in the mentioned newsgroup threads.
as you already addressed the architecute, i'd like to give a short overview
of the architecture i'm planning to use:

<pre>
+----------------+
| .... |
+---------+------+
| Service | |
+---------+ DOM |
| DAO | |
+---------+------+
| Database |
+----------------+
</pre>

- Database: a relational DBMS

- DOM: the business objects representing the DB structure (mapped with hibernate annotations),
these are basically POJOs which just keep the attributes and provide getters/settters for them

- DAO: the data access objects. for each DOM object there is a DAO object which encapsulate
the basic CRUD (create, read, update, delete) operations. in my case i'm using spring and
the hibernate templates. this layer doesn't do any transaction or session management

- Service: this is the business-service layer. it encapsulates the business logic for the DOM objects.
for each DOM there is a Service-Object which provides the methods and logic which the application
uses to act which the business objects.
it uses the DAO layer to access the database. this layer is responsible for managing the transactions
and services transactions because this layer knows which method needs a session/transaction.
i'm using spring and the @Transactional annotations here.

now using these layers, without thinking about a presentation layer, is no problem. the business layer
methods are annotated to use the transaction, the spring framework handles the rest of the session/transaction
management. this works quite well when testing it with simple java code (insert, read objects etc.).

don't know exactly if this architecture is a best practise?!! maybe any comments on that?

the task now is to set up a RAP frontend application to work on these layers. as you already
mentioned, stefan, the problem is to make spring 'RAP-aware' since it is not a traditional Serlvet Environment.
the RAP app is encapsulated in a bridge-servlet that contains the OSGi and eclipse portion of the RAP app.
another problem is the multi-user environment of a RAP app. this can be addressed with session scoped beans
as soon as the spring framework has been made 'RAP-aware'.

the other posts in this newsgroup about integrating spring into RAP already state many of the problems
that come along with this concept. basically the only task that are making problems is the presentation layer,
the view respectively. so the problem is to set up a RAP app on this architecture without doing too much
'hacking' and polluting RAP code with other concerns.

of course i'd like to follow the RCP paradigm, having views, content provider, model under these views etc.

now i need some pointers how to connect the presentation with the data. i can use the business layer to
load objects, by getAll() for example, and put these objects into the proper jface viewers (with a content
provider). but then the problem with the lazy loading appears when i access values of these models in the
view (getName()... for example) because the session is closed after these objects are fetched by the business-service
layer. this is particulary problematic when using trees, where the children are fetched when a node is expanded...

the OpenSessionInView pattern seems to be a possible solution because, correct me if i'm wrong,
when the response is rendered, all of the business logic and object access is done, assuming that the operation
is done in the UIThread! but not every maybe not every request does net a session, does that scale when more user
are using the application simultaneously and every request (every klick) calls a session??

i hope my problem is somehow understandably, i'm just writing the problems that i see because this are
the issues where i see the problems and don't know how to solve them in a proper way.


i think this topic is especially interesting because this concerns every application in a JEE environment
that wants to use the wide-spread frameworks (such as spring, hibernate) and RAP as the application/presentation tire.


i'm looking forward to comments from your side!


thx!

greetings,
ben




stefan.hansel@tolina.de schrieb:
> Hi Benjamin,
>
> our App uses JDO + Spring, but the fundamental problems are the same as
> with Spring+ Hibernate/JPA.
> Have a look for 'Integrating Spring: OpenSessionInView-Pattern in RAP' in
> this newgroups for further information and links to other posts.
>
> Actually in RAP you still have proper requests (typically button-clicks),
> unfortunately they don't work with Spring out of the box, as RAP has it's
> own UI-Threads and Spring heavily uses ThreadLocals to handle
> request+sessionstate.
> Basically in a PhaseListener (which is already called on the UI-Thread
> before and after application-code handles the request) we trigger the
> Spring-Initialization that they typically do in a ServletListener.
>
> Thus we get a proper working ApplicationContext of Spring which handles
> all JDO-stuff (building PersistenceManagerFactories).
> Furthermore the @Transaction-annotiations are fully working and Spring
> handles retrieving and releasing PersistenceManagers
> (=Sessions/EntitiyManager in Hibernate/JPA) like it does in any other app.
>
> It depends on your application / architecture how far you go with lazy
> loading.
> In a classic 3-tier-architecture, the view can't do any lazy-loading
> anymore (Sessions are closed on leaving the transaction of a
> Manager/Service-class).
> Anyway - there is a pattern called 'OpenSessionInView' - which some don't
> like (at least there is a lot of discussion about pro/cons) - but we do !
>
> Coming from Swing, where our PersistenceManagers where open all the time
> (thus lazy-loading working all the time), we didn't have a problem to use
> the pattern in RAP as well.
>
> One gotcha remained still: as with OpenSessionInView the session lasts as
> long as the Request, lazy-loading only works in the current request.
> This is kind of problematic, because on each subsequent button-click you
> can't use the object anymore. I think with hibernate merging a detached
> object with a new session might be easier as with JDO.
>
> Anyway - in our app, the view is not allowed to hold references to the
> entities, otherwise we'd have a lot of problems with accessing fields of
> 'old' detachted objects from previous request.
> Instead they only hold the ID of the objects in question and to make it
> easier, we have a generic proxy-object which handles this automatically.
>
> This is also done because of memory-considerations:
> It doesn't make sense, to retrieve an entity, put all values into
> GUI-fields and then keep the entity in memory, until the user decides what
> to do next. The memory is always filled twice (all values are stored in
> the GUI fields, furthermore in the Entitiy itself).
> When the view only remembers the ID of the entity, we save up to 50% of
> memory per session.
>
>
Re: Small talk about RAP and using a persistence layer (e.g. Hibernate) [message #131745 is a reply to message #131724] Thu, 07 May 2009 13:19 Go to previous messageGo to next message
Stefan Hansel is currently offline Stefan HanselFriend
Messages: 103
Registered: July 2009
Senior Member
Dies ist eine mehrteilige Nachricht im MIME-Format.
--=_alternative 0049339CC12575AF_=
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable

>> now i need some pointers how to connect the presentation with the data.

There are basically 3 ways you can go:

1) NoOpenSessionInView:=20
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D
Now your Service-layer needs to know in advance, how much data is needed=20
by the view to preload the data.
This is the typical scenario, when a view is only available remotely where =

you have to solve the same (nontrivial) problem of a not working=20
lazy-loading in the view-layer.
It's then always a fight between coarse/finegrained access and typically=20
you not only have one 'findEmployeeByName' but in addition=20
'findEmployeeByNameWithDetails'.

For a tree-scenario this would mean to=20
1a) fetch the whole tree at once (in the server only suitable for small=20
trees),=20
1b) or have services which mimic a lazy loading API (getTreeRootItem,=20
getChildItems ...)

For 1a your View-TreeModel is easy of course - just take some simple=20
implementation and push all your data into it. Maybe even use the original =

(preloaded) entities.
Takes a lot of memory of course, when the user doesnt expand the=20
tree.
For 1b you need a View-TreeModel which talks all the time with the service =

API. This is possible with your own implementation of the=20
Model-interfaces.=20
Your tree wouldn't use your original entities then.

Anyway - these are all standard patterns which every Swing/SWT-Developer=20
who needs to talk to remote EJBs or Webservices must cope with as well.
Only bad (or should we call them 'pragmatic' ? :D ) developers built=20
fat-clients, which (through a layered API with view/service/DAO/OR-Mapper) =

talked to the DB directly.
At least their live was easy *g*.

2) OpenSessionInView (works only when view + service-layer are run on the =

same VM)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D
Here it might still make sense to have a service layer with=20
'findEmployeeByNameWithDetails'-methods. But just to optimize=20
database-roundtrips as you can fine-tune Fetch-Groups according to the use =

case.
Typically this only cames later in the project (show me a project, where=20
performance is handled first ;) ) as you can easily work with lazy loading =

up to then.

Coming back to your Tree Scenario:=20
You still can't use a simple TreeModel, as - when accessing data - you=20
need to reattach your entities in each request to make lazy-loading work=20
again.
As its cumbersome to think of it all the time, we use ObjectProxies when=20
holding references to entities.=20
In our case it looks as simple as this:=20

public interface IObjectProxy<T> {
/**
* @return Liefert eine aktuelle Instanz des Objekts, welches von=20
diesem Proxy repr=E4sentiert wird.<br>
* <b>ACHTUNG:</b> Diese Methode wird relativ h=E4ufig aufgerufen=20
... Implementierungen sollten das zur=FCckgegebene
* Objekt also m=F6glichst lange cachen (typischerweise mind. f=FCr=
=20
den aktuellen Request).
*/
public T getObject();

/**
* Liefert true, wenn das gegebene Objekt das Gleiche ist, das im=20
Proxy steckt. false sonst.<br/>
* Achtung: Das Resultat entspricht nicht unbedingt dem=20
Objektvergleich mit dem '=3D=3D'-Operator, den man in Java kennt.
*=20
* @param o
*/
public boolean objectIsSameAs(Object o);

}

The tree only holds a Reference to an IObjectProxy<SomeEntity> but through =

'getObject()' still works all the time on the real-entity and then=20
accesses the lazy-loaded children for the tree.
This programming experience is still quite comfortable.=20
To get a new proxy there is an ObjectProxyFactory as well.

A critic would notice, that the objectProxy is only some kind of generic=20
DAO, that the view has access to.=20
And if he is mean he notices that a view shouldn't have access to a DAO.

In such a case you must go back to 1), live with the consequences (longer=20
time to market) but have a purer architecture.
Whoever pays the money for your developers has to decide ;-) ...


3) OpenSessionAllTheTime
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D
Good old fat-client way. JDO-PersistenceManager=20
(=3DHibernate-Session/JPA-EntityManager) open all the time. One for each=20
user to avoid multithreading issues.
You have to clear the cache from time to time to avoid optimistic-locking.
Easy to hack your GUI along, even in RWT/RAP. Lazy loading working all the =

time without workaround :D

I wouldn't advise this way for a server, as the JDO/JPA-Spec demands to=20
cache all retrieved entities. This could lead to a big memory-overhead.
If you only serve a given amount of users, this isn't too bad I guess.

To be honest: in selected places we even have a long living=20
PersistenceManager (long-living=3Dserver-session).=20
Typically for read-only configuration stuff, which would have been cached=20
in the session anyway. No need to close the PersistenceManager then all=20
the time.

>> but then the problem with the lazy loading appears when i access values =

of these models in the
>> view (getName()... for example) because the session is closed after=20
these objects are fetched by the business-service layer.=20
Just to be correct: with openSessionInView, the session is closed at the=20
end of the request, not when you leave the business-service-layer.
Problems only start on subsequent request, if you don't work with proxies=20
or other means.

>> but not every maybe not every request does net a session,
Yeah you are right. All timer based tasks typically are no 'real' request. =

You have to simulate a request there as well - but that's what the=20
PhaseListener is doing all the time.=20
Works perfectly on other threads as well. How you define the lifecycle of=20
'session' and 'request' lies in your hands.

>> does that scale when more user are using the application simultaneously =

and every request (every klick) calls a session??
I hope so, otherwise we will get problems soon ;)=20
Instantiating a PersistenceManager in JDO doesn't cost much. Actually it's =

just a cache with some APIs around. I think the same is true for=20
hibernate.
The cost only begins when you access the service API (Transaction,=20
reloading objects, doing queries) or the object-Proxy as then connections=20
from the pool are taken and used.
Simple RWT-ActionListener which just change some values (without accessing =

the Service-Layer) are almost transparent, performance-wise.

The use of ObjectProxies and the service-layer itself in my opinion is as=20
performant as if you'd work stateless as in 1).
A classic service-Layer would have to load each object as well all the=20
time. That's where the second-level caches of Hibernate & CO bring their=20
power into play.


All in all - of course there's no perfect architecture (otherwise we=20
didn't need so many architects/developers discussing all the time).
I'd rather love to be in a position like the RAP-developers who just need=20
to think about simple APIs.=20
Their live must be a dream *GGGGGGGGG*

--=_alternative 0049339CC12575AF_=
Content-Type: text/html; charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable


<br><tt><font size=3D2>&gt;&gt; now i need some pointers how to connect the
presentation with the data.</font></tt>
<br>
<br><tt><font size=3D2>There are basically 3 ways you can go:</font></tt>
<br>
<br><tt><font size=3D2>1) NoOpenSessionInView: </font></tt>
<br><tt><font size=3D2>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D</font></tt>
<br><tt><font size=3D2>Now your Service-layer needs to know in advance, how
much data is needed by the view to preload the data.</font></tt>
<br><tt><font size=3D2>This is the typical scenario, when a view is only
available remotely where you have to solve the same (nontrivial) problem
of a not working lazy-loading in the view-layer.</font></tt>
<br><tt><font size=3D2>It's then always a fight between coarse/finegrained
access and typically you not only have one 'findEmployeeByName' but in
addition 'findEmployeeByNameWithDetails'.</font></tt>
<br>
<br><tt><font size=3D2>For a tree-scenario this would mean to </font></tt>
<br><tt><font size=3D2>1a) fetch the whole tree at once (in the server only
suitable for small trees), </font></tt>
<br><tt><font size=3D2>1b) or have services which mimic a lazy loading API
(getTreeRootItem, getChildItems ...)</font></tt>
<br>
<br><tt><font size=3D2>For 1a your View-TreeModel is easy of course - just
take some simple implementation and push all your data into it. Maybe even
use the original (preloaded) entities.</font></tt>
<br><tt><font size=3D2>&nbsp; &nbsp; &nbsp; &nbsp;Takes a lot of memory of
course, when the user doesnt expand the tree.</font></tt>
<br><tt><font size=3D2>For 1b you need a View-TreeModel which talks all the
time with the service API. This is possible with your own implementation
of the Model-interfaces. </font></tt>
<br><tt><font size=3D2>&nbsp; &nbsp; &nbsp; &nbsp;Your tree wouldn't use
your original entities then.</font></tt>
<br>
<br><tt><font size=3D2>Anyway - these are all standard patterns which every
Swing/SWT-Developer who needs to talk to remote EJBs or Webservices must
cope with as well.</font></tt>
<br><tt><font size=3D2>Only bad (or should we call them 'pragmatic' ? :D
) developers built fat-clients, which (through a layered API with view/serv=
ice/DAO/OR-Mapper)
talked to the DB directly.</font></tt>
<br><tt><font size=3D2>At least their live was easy *g*.</font></tt>
<br>
<br><tt><font size=3D2>2) OpenSessionInView &nbsp;(works only when view +
service-layer are run on the same VM)</font></tt>
<br><tt><font size=3D2>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D</font></tt>
<br><tt><font size=3D2>Here it might still make sense to have a service lay=
er
with 'findEmployeeByNameWithDetails'-methods. But just to optimize database=
-roundtrips
as you can fine-tune Fetch-Groups according to the use case.</font></tt>
<br><tt><font size=3D2>Typically this only cames later in the project (show
me a project, where performance is handled first ;) ) as you can easily
work with lazy loading up to then.</font></tt>
<br>
<br><tt><font size=3D2>Coming back to your Tree Scenario: </font></tt>
<br><tt><font size=3D2>You still can't use a simple TreeModel, as - when
accessing data - you need to reattach your entities in each request to
make lazy-loading work again.</font></tt>
<br><tt><font size=3D2>As its cumbersome to think of it all the time, we
use ObjectProxies when holding references to entities. </font></tt>
<br><tt><font size=3D2>In our case it looks as simple as this: </font></tt>
<br>
<br><font size=3D2 color=3D#820040 face=3D"Courier New"><b>public</b></font=
><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#820040 face=3D"Courier New"><b>interface</b>=
</font><font size=3D2 face=3D"Courier New">
IObjectProxy&lt;T&gt; {</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; </font>=
<font size=3D2 color=3D#4040c2 face=3D"Courier New">/**</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*</font><font siz=
e=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#71b2cf face=3D"Courier New"><b>@return</b></=
font><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Liefert</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">eine</font><font=
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">aktuelle</font><=
font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Instanz</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">des</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Objekts,</font><=
font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">welches</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">von</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">diesem</font><fo=
nt size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Proxy</font><fon=
t size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">repr=E4sentiert<=
/font><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">wird.</font><fon=
t size=3D2 color=3D#8f8f8f face=3D"Courier New">&lt;br&gt;</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*</font><font siz=
e=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#8f8f8f face=3D"Courier New">&lt;b&gt;</font>=
<font size=3D2 color=3D#4040c2 face=3D"Courier New">ACHTUNG:</font><font si=
ze=3D2 color=3D#8f8f8f face=3D"Courier New">&lt;/b&gt;</font><font size=3D2=
face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Diese</font><fon=
t size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Methode</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">wird</font><font=
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">relativ</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">h=E4ufig</font><=
font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">aufgerufen</font=
><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">...</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Implementierunge=
n</font><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">sollten</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">das</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">zur=FCckgegebene=
</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*</font><font siz=
e=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Objekt</font><fo=
nt size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">also</font><font=
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">m=F6glichst</fon=
t><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">lange</font><fon=
t size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">cachen (typische=
rweise
mind. f=FCr den aktuellen Request).</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*/</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; </font>=
<font size=3D2 color=3D#820040 face=3D"Courier New"><b>public</b></font><fo=
nt size=3D2 face=3D"Courier New">
T <b>getObject</b>();</font>
<br>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; </font>=
<font size=3D2 color=3D#4040c2 face=3D"Courier New">/**</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*</font><font siz=
e=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Liefert</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">true,</font><fon=
t size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">wenn</font><font=
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">das</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">gegebene</font><=
font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Objekt</font><fo=
nt size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">das</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Gleiche</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">ist,</font><font=
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">das</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">im</font><font s=
ize=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Proxy</font><fon=
t size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">steckt.</font><f=
ont size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">false</font><fon=
t size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">sonst.&lt;br/&gt=
;</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*</font><font siz=
e=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Achtung:</font><=
font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Das</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Resultat</font><=
font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">entspricht</font=
><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">nicht</font><fon=
t size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">unbedingt</font>=
<font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">dem</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Objektvergleich<=
/font><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">mit</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">dem</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">'=3D=3D'</font><=
font size=3D2 color=3D#8f8f8f face=3D"Courier New">-</font><font size=3D2 c=
olor=3D#4040c2 face=3D"Courier New">Operator,</font><font size=3D2 face=3D"=
Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">den</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">man</font><font =
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">in</font><font s=
ize=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">Java</font><font=
size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">kennt.</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*</font><font siz=
e=3D2 face=3D"Courier New">
</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*</font><font siz=
e=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#71b2cf face=3D"Courier New"><b>@param</b></f=
ont><font size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#4040c2 face=3D"Courier New">o</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<=
/font><font size=3D2 color=3D#4040c2 face=3D"Courier New">*/</font>
<br><font size=3D2 face=3D"Courier New">&nbsp; &nbsp; &nbsp; &nbsp; </font>=
<font size=3D2 color=3D#820040 face=3D"Courier New"><b>public</b></font><fo=
nt size=3D2 face=3D"Courier New">
</font><font size=3D2 color=3D#820040 face=3D"Courier New"><b>boolean</b></=
font><font size=3D2 face=3D"Courier New">
<b>objectIsSameAs</b>(Object </font><font size=3D2 color=3D#820040 face=3D"=
Courier New">o</font><font size=3D2 face=3D"Courier New">);</font>
<br>
<br><font size=3D2 face=3D"Courier New">}</font>
<br>
<br><tt><font size=3D2>The tree only holds a Reference to an IObjectProxy&l=
t;SomeEntity&gt;
but through 'getObject()' still works all the time on the real-entity and
then accesses the lazy-loaded children for the tree.</font></tt>
<br><tt><font size=3D2>This programming experience is still quite comfortab=
le.
</font></tt>
<br><tt><font size=3D2>To get a new proxy there is an ObjectProxyFactory
as well.</font></tt>
<br>
<br><tt><font size=3D2>A critic would notice, that the objectProxy is only
some kind of generic DAO, that the view has access to. </font></tt>
<br><tt><font size=3D2>And if he is mean he notices that a view shouldn't
have access to a DAO.</font></tt>
<br>
<br><tt><font size=3D2>In such a case you must go back to 1), live with the
consequences (longer time to market) but have a purer architecture.</font><=
/tt>
<br><tt><font size=3D2>Whoever pays the money for your developers has to
decide ;-) ...</font></tt>
<br>
<br>
<br><tt><font size=3D2>3) OpenSessionAllTheTime</font></tt>
<br><tt><font size=3D2>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D</font></tt>
<br><tt><font size=3D2>Good old fat-client way. JDO-PersistenceManager (=3D=
Hibernate-Session/JPA-EntityManager)
open all the time. One for each user to avoid multithreading issues.</font>=
</tt>
<br><tt><font size=3D2>You have to clear the cache from time to time to avo=
id
optimistic-locking.</font></tt>
<br><tt><font size=3D2>Easy to hack your GUI along, even in RWT/RAP. Lazy
loading working all the time without workaround :D</font></tt>
<br>
<br><tt><font size=3D2>I wouldn't advise this way for a server, as the JDO/=
JPA-Spec
demands to cache all retrieved entities. This could lead to a big memory-ov=
erhead.</font></tt>
<br><tt><font size=3D2>If you only serve a given amount of users, this isn't
too bad I guess.</font></tt>
<br>
<br><tt><font size=3D2>To be honest: in selected places we even have a long
living PersistenceManager (long-living=3Dserver-session). <br>
Typically for read-only configuration stuff, which would have been cached
in the session anyway. No need to close the PersistenceManager then all
the time.</font></tt>
<br>
<br><tt><font size=3D2>&gt;&gt; but then the problem with the lazy loading
appears when i access values of these models in the<br>
&gt;&gt; view (getName()... for example) because the session is closed
after these objects are fetched by the business-service layer. </font></tt>
<br><tt><font size=3D2>Just to be correct: with openSessionInView, the sess=
ion
is closed at the end of the request, not when you leave the business-servic=
e-layer.</font></tt>
<br><tt><font size=3D2>Problems only start on subsequent request, if you
don't work with proxies or other means.</font></tt>
<br>
<br><tt><font size=3D2>&gt;&gt; but not every maybe not every request does
net a session,</font></tt>
<br><tt><font size=3D2>Yeah you are right. All timer based tasks typically
are no 'real' request. You have to simulate a request there as well - but
that's what the PhaseListener is doing all the time. <br>
Works perfectly on other threads as well. How you define the lifecycle
of 'session' and 'request' lies in your hands.</font></tt>
<br>
<br><tt><font size=3D2>&gt;&gt; does that scale when more user are using
the application simultaneously and every request (every klick) calls a
session??</font></tt>
<br><tt><font size=3D2>I hope so, otherwise we will get problems soon ;)
</font></tt>
<br><tt><font size=3D2>Instantiating a PersistenceManager in JDO doesn't
cost much. Actually it's just a cache with some APIs around. I think the
same is true for hibernate.</font></tt>
<br><tt><font size=3D2>The cost only begins when you access the service API
(Transaction, reloading objects, doing queries) or the object-Proxy as
then connections from the pool are taken and used.</font></tt>
<br><tt><font size=3D2>Simple RWT-ActionListener which just change some val=
ues
(without accessing the Service-Layer) are almost transparent, performance-w=
ise.</font></tt>
<br>
<br><tt><font size=3D2>The use of ObjectProxies and the service-layer itself
in my opinion is as performant as if you'd work stateless as in 1).</font><=
/tt>
<br><tt><font size=3D2>A classic service-Layer would have to load each obje=
ct
as well all the time. That's where the second-level caches of Hibernate
&amp; CO bring their power into play.</font></tt>
<br>
<br>
<br><tt><font size=3D2>All in all - of course there's no perfect architectu=
re
(otherwise we didn't need so many architects/developers discussing all
the time).</font></tt>
<br><tt><font size=3D2>I'd rather love to be in a position like the RAP-dev=
elopers
who just need to think about simple APIs. </font></tt>
<br><tt><font size=3D2>Their live must be a dream *GGGGGGGGG*</font></tt>
<br>
--=_alternative 0049339CC12575AF_=--
Re: Small talk about RAP and using a persistence layer (e.g. Hibernate) [message #132204 is a reply to message #131745] Mon, 11 May 2009 10:50 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: benjamin.wolff.web.de

please see my comments below.

stefan.hansel@tolina.de schrieb:
>>> now i need some pointers how to connect the presentation with the data.
>
> There are basically 3 ways you can go:
>
> 1) NoOpenSessionInView:
> ========================
> Now your Service-layer needs to know in advance, how much data is needed
> by the view to preload the data.
> This is the typical scenario, when a view is only available remotely where
> you have to solve the same (nontrivial) problem of a not working
> lazy-loading in the view-layer.
> It's then always a fight between coarse/finegrained access and typically
> you not only have one 'findEmployeeByName' but in addition
> 'findEmployeeByNameWithDetails'.
>
> For a tree-scenario this would mean to
> 1a) fetch the whole tree at once (in the server only suitable for small
> trees),
> 1b) or have services which mimic a lazy loading API (getTreeRootItem,
> getChildItems ...)
>


> For 1a your View-TreeModel is easy of course - just take some simple
> implementation and push all your data into it. Maybe even use the original
> (preloaded) entities.
> Takes a lot of memory of course, when the user doesnt expand the
> tree.
> For 1b you need a View-TreeModel which talks all the time with the service
> API. This is possible with your own implementation of the
> Model-interfaces.
> Your tree wouldn't use your original entities then.
>
> Anyway - these are all standard patterns which every Swing/SWT-Developer
> who needs to talk to remote EJBs or Webservices must cope with as well.


i see, so the methods you described above are 'standards' in such an environment?
good to know.


> Only bad (or should we call them 'pragmatic' ? :D ) developers built
> fat-clients, which (through a layered API with view/service/DAO/OR-Mapper)
> talked to the DB directly.
> At least their live was easy *g*.


now i'm a little bit confused. isn't the layered view/service/DAO/... architecture
considered to be good design?! :) Since the DAO should be responsible


>
> 2) OpenSessionInView (works only when view + service-layer are run on the
> same VM)
> =======================
> Here it might still make sense to have a service layer with
> 'findEmployeeByNameWithDetails'-methods. But just to optimize
> database-roundtrips as you can fine-tune Fetch-Groups according to the use
> case.
> Typically this only cames later in the project (show me a project, where
> performance is handled first ;) ) as you can easily work with lazy loading
> up to then.
>
> Coming back to your Tree Scenario:
> You still can't use a simple TreeModel, as - when accessing data - you
> need to reattach your entities in each request to make lazy-loading work
> again.
> As its cumbersome to think of it all the time, we use ObjectProxies when
> holding references to entities.
> In our case it looks as simple as this:
>
> public interface IObjectProxy<T> {
> /**
> * @return Liefert eine aktuelle Instanz des Objekts, welches von
> diesem Proxy repräsentiert wird.<br>
> * <b>ACHTUNG:</b> Diese Methode wird relativ häufig aufgerufen
> ... Implementierungen sollten das zurückgegebene
> * Objekt also möglichst lange cachen (typischerweise mind. für
> den aktuellen Request).
> */
> public T getObject();
>
> /**
> * Liefert true, wenn das gegebene Objekt das Gleiche ist, das im
> Proxy steckt. false sonst.<br/>
> * Achtung: Das Resultat entspricht nicht unbedingt dem
> Objektvergleich mit dem '=='-Operator, den man in Java kennt.
> *
> * @param o
> */
> public boolean objectIsSameAs(Object o);
>
> }
>
> The tree only holds a Reference to an IObjectProxy<SomeEntity> but through
> 'getObject()' still works all the time on the real-entity and then
> accesses the lazy-loaded children for the tree.
> This programming experience is still quite comfortable.
> To get a new proxy there is an ObjectProxyFactory as well.
>
> A critic would notice, that the objectProxy is only some kind of generic
> DAO, that the view has access to.
> And if he is mean he notices that a view shouldn't have access to a DAO.
>
> In such a case you must go back to 1), live with the consequences (longer
> time to market) but have a purer architecture.
> Whoever pays the money for your developers has to decide ;-) ...
>


So your tree would actually hold only IObjectProxy<SomeEntity> objects, every
time you access a node the getObject() method is called?! but for a tree
you need a model somewhere in the background representing the tree hierarchy
which you can traverse etc. don't you? i don't quite get where the proxy is located
i such a tree context. maybe you could provide a cheap example?

i tried to get the OpenInSessionView pattern to work with RAP following you example
in the 'Integrating Spring: OpenSessionInView-Pattern in RAP' post in this newsgroup
but couldn't get it to work. to i have to add something special in my applicationContext.xml
file?!

WebApplicationContext wac =
WebApplicationContextUtils.getRequiredWebApplicationContext( RWT.getRequest().getSession().getServletContext());
openPersistenceManagerInViewInterceptor = (OpenPersistenceManagerInViewInterceptor) wac.getBean("openPersistenceManagerInViewInterceptor",
OpenPersistenceManagerInViewInterceptor.class);

from where do i get the proper WebApplicationContext?

it fails with the exception:
SCHWERWIEGEND: Could not execute PhaseListener before phase 'PREPARE_UI_ROOT'.
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?

does this actually work when starting out of Eclipse IDE due to the embedded jetty container?

any hints would be highly appreciated :).

>
> 3) OpenSessionAllTheTime
> =========================
> Good old fat-client way. JDO-PersistenceManager
> (=Hibernate-Session/JPA-EntityManager) open all the time. One for each
> user to avoid multithreading issues.
> You have to clear the cache from time to time to avoid optimistic-locking.
> Easy to hack your GUI along, even in RWT/RAP. Lazy loading working all the
> time without workaround :D
>
> I wouldn't advise this way for a server, as the JDO/JPA-Spec demands to
> cache all retrieved entities. This could lead to a big memory-overhead.
> If you only serve a given amount of users, this isn't too bad I guess.
>
> To be honest: in selected places we even have a long living
> PersistenceManager (long-living=server-session).
> Typically for read-only configuration stuff, which would have been cached
> in the session anyway. No need to close the PersistenceManager then all
> the time.
>
>>> but then the problem with the lazy loading appears when i access values
> of these models in the
>>> view (getName()... for example) because the session is closed after
> these objects are fetched by the business-service layer.
> Just to be correct: with openSessionInView, the session is closed at the
> end of the request, not when you leave the business-service-layer.
> Problems only start on subsequent request, if you don't work with proxies
> or other means.
>
>>> but not every maybe not every request does net a session,
> Yeah you are right. All timer based tasks typically are no 'real' request.
> You have to simulate a request there as well - but that's what the
> PhaseListener is doing all the time.
> Works perfectly on other threads as well. How you define the lifecycle of
> 'session' and 'request' lies in your hands.
>
>>> does that scale when more user are using the application simultaneously
> and every request (every klick) calls a session??
> I hope so, otherwise we will get problems soon ;)
> Instantiating a PersistenceManager in JDO doesn't cost much. Actually it's
> just a cache with some APIs around. I think the same is true for
> hibernate.


yes, you are right. according to the hibernate docu the Session object is also
supposed to have request scope, so there also shouldn't be any performance issues.


> The cost only begins when you access the service API (Transaction,
> reloading objects, doing queries) or the object-Proxy as then connections
> from the pool are taken and used.
> Simple RWT-ActionListener which just change some values (without accessing
> the Service-Layer) are almost transparent, performance-wise.
>
> The use of ObjectProxies and the service-layer itself in my opinion is as
> performant as if you'd work stateless as in 1).
> A classic service-Layer would have to load each object as well all the
> time. That's where the second-level caches of Hibernate & CO bring their
> power into play.
>
>
> All in all - of course there's no perfect architecture (otherwise we
> didn't need so many architects/developers discussing all the time).
> I'd rather love to be in a position like the RAP-developers who just need
> to think about simple APIs.
> Their live must be a dream *GGGGGGGGG*
>


:)))

thanks so far for your (very good) input!! i really appreciate your help on this,
nevertheless i'm getting a little nervous concerning the complexity of my project
when looking in the future and taking the available time into consideration :/.
the UI presentation for viewing and manipulating the data is also only one part
of my work, the other is supposed to be conerned with automatic custom OpenOffice file
creation out of the RAP application. aargh :))


greetings,
ben
Re: Small talk about RAP and using a persistence layer (e.g. Hibernate) [message #132333 is a reply to message #132204] Tue, 12 May 2009 11:45 Go to previous message
Stefan Hansel is currently offline Stefan HanselFriend
Messages: 103
Registered: July 2009
Senior Member
>> i see, so the methods you described above are 'standards' in such an
environment? good to know.

Um.
Ask three architects and you will get 10 answers :D
With architecture there are no standards, just common patterns. I suggest
reading http://martinfowler.com/eaaCatalog/ or the corresponding book
http://www.amazon.de/Patterns-Enterprise-Application-Archite cture-Martin/dp/0321127420
for deeper discussion about all that.

>> now i'm a little bit confused. isn't the layered view/service/DAO/...
architecture
>> considered to be good design?! :) Since the DAO should be responsible
I depends on how you implement it. There are people how will tell you,
that the classic DAO-pattern is (mostly) dead:

For a good reading I suggest Adam Bien:
http://www.adam-bien.com/roller/abien/entry/daos_aren_t_dead _but
http://www.adam-bien.com/roller/abien/entry/you_should_dao_i f

And if you want to get rid of the Service-Layer as well ;-) :
http://www.adam-bien.com/roller/abien/entry/should_jpa_entit ies_contain_business
also Eric Evans 'Domain Driven Design' goes into that direction.

So far to confuse you more with 'standards' *g*

>> So your tree would actually hold only IObjectProxy<SomeEntity> objects,
every
>> time you access a node the getObject() method is called?! but for a
tree
>> you need a model somewhere in the background representing the tree
hierarchy
>> which you can traverse etc. don't you?
The Tree-Structure lies in the data-model. That's your normal persistent
entities.
If a TreeItem has to reference an Entity, than the proxy is just
inbetween.
If you need children of a treeitem, all you have to do is call
treeitem.getProxy().getObject().getChildren().

>> from where do i get the proper WebApplicationContext?
Um,
as we use RAP-standalone mode, we have it in the web.xml. The following is
described in the Spring-Doccs.
The ContextLoaderLister provides the WebApplicationContext to the session.


<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/de/tolina/product/db.xml
classpath:/de/tolina/product/spring/dao.xml
classpath:/de/tolina/product/spring/service.xml
</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

Don't know how this is handled in OSGI mode.


>> the other is supposed to be conerned with automatic custom OpenOffice
file creation out of the RAP application. aargh :))
My company sells consulting :D
And of course we have a solution for that ... Basically we coded a
templating engine for RTF-Documents (so working for WordPro and Word as
well).
We write normal RTF-docs with all possible layouting nightmare, and have
some 'simple' text-substitution. As we are able to expand tables, repeat
blocks or having conditional blocks you can get quite sophisticated
documents.

Unfortunately the RTF-Spec for Word is about 200 pages ... though you only
need to understand a subset to manipulate a doc.

These documents are opened from within RAP in their native Word-Processor,
can be changed by the user and are reuploaded automatically, when the
users close the document.

Good luck with your investigation, plan a lot of time, it won't be easy
...
Previous Topic:Marking in the process image
Next Topic:Styling CTabItem
Goto Forum:
  


Current Time: Wed Dec 01 09:54:24 GMT 2021

Powered by FUDForum. Page generated in 16.50322 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top