Discussion:
[Middlegen-user] Reentrant VOs
Dean Des Rosiers
2003-04-24 12:15:22 UTC
Permalink
I recently needed to compare several domain persistence layer options to a
client. I used Middlegen/XDoclet/MVCSoft to show how CMP works.
Unfortunately I needed to make my relationships uni-directional for this to
work. Naturally, this had unwanted repercussions in the rest of my code.

I had an idea for a solution that I’d like to float. Call it a “third way”
in addition Evind’s previous two. The problem seems to be letting your VO
code know when to “stop.” To do this I propose a string that I call a
“specifier.” This string describes the object graph to be returned.

Consider the following:
A Restaurant has zero or more MenuItems
A MenuItem has one and only one Restaurant
A Restaurant has zero or more ZipCodes
A ZipCode has zero or more Restaurants
A ZipCode has one or more Municipalities
A Municipality has one or more ZipCodes

A naïve implementation and deployment results in the VO reentrant problem
since both the above relationships are bi-directional. The VO code does not
know when to stop. Consider the following strings:

(zipCodes(municipalities), menuItems)
(zipCodes, menuItems)

Where the names are names of properties returning collections, the
parentheses denote hierarchical nesting and the commas separate a bean’s
property names.

If the first string were passed in to a Restaurant’s getValue() method the
method would return the matching properties as usual, but when it called
getValue() on each member returned by Restaurant’s getZipCodes() method it
would pass in whatever was between the parentheses following “zipCodes” in
the specifier string (in this case “municipalities”). ZipCode’s getValue()
method would then invoke the bean’s getMunicipalities() method, passing no
specifier string. As a result, the Municipality bean would not call its
getZipCodes() method.

The second string would put into the Value Object graph only the ZipCodes
and MenuItems associated with the Restaurant. The ZipCodes would not have
their Municipalities loaded and the MenuItems would not have their
Restaurant loaded.

I’ve used this method in another situation and have a small amount of
parsing code available. I’m not at all sure how this fits in with
Middlegen, XDoclet, or even with *updating* CMP objects.

I just wanted to get this documented, off my chest, and reviewed by my
peers.

Thanks,
Dean Des Rosiers
Eivind Waaler
2003-04-28 12:15:20 UTC
Permalink
These are quite interesting ideas.

As far as I can see, these are much the same ideas that are behind the
ValueTreeBuilder class in the Value Object patch:

http://sourceforge.net/tracker/?func=3Ddetail&aid=3D636987&group_id=3D36044=
&atid=3D415992

Right now I'm generating the value objects with the "light" objects
returned in all relationships. This is a quite simple solution, and will
only give relationships over 2 levels.

I'll look into this ValueTreeBuilder/VO graph/map feature next. As far as
I can see, this will really not necesarily mean generating things in a
different manner. We could ship a special edition of this utility with
Middlegen together with some document describing it's use maybe? That way
we'd provide the following functionality:

- Generate 2 level relationships directly.
- Provide a TreeBuilder for building structures containing more than 2
levels.
- Optionally allow "full relationship" support, meaning the user would
have to make sure there are no cyclic relationships.

I think this is beginning to sound like quite a flexible solution. At
least until XDoclet is able to generate without us having to worry about
the reentrancy. Any comments, more ideas on this?

=2Eeivind
I recently needed to compare several domain persistence layer options to =
a
client. I used Middlegen/XDoclet/MVCSoft to show how CMP works.
Unfortunately I needed to make my relationships uni-directional for this =
to
work. Naturally, this had unwanted repercussions in the rest of my code.
=20
I had an idea for a solution that I=92d like to float. Call it a =93thir=
d way=94
in addition Evind=92s previous two. The problem seems to be letting your=
VO
code know when to =93stop.=94 To do this I propose a string that I call =
a
=93specifier.=94 This string describes the object graph to be returned.
=20
A Restaurant has zero or more MenuItems
A MenuItem has one and only one Restaurant
A Restaurant has zero or more ZipCodes
A ZipCode has zero or more Restaurants
A ZipCode has one or more Municipalities
A Municipality has one or more ZipCodes
=20
A na=EFve implementation and deployment results in the VO reentrant probl=
em
since both the above relationships are bi-directional. The VO code does =
not
=20
(zipCodes(municipalities), menuItems)
(zipCodes, menuItems)
=20
Where the names are names of properties returning collections, the
parentheses denote hierarchical nesting and the commas separate a bean=92=
s
property names.
=20
If the first string were passed in to a Restaurant=92s getValue() method =
the
method would return the matching properties as usual, but when it called
getValue() on each member returned by Restaurant=92s getZipCodes() method=
it
would pass in whatever was between the parentheses following =93zipCodes=
=94 in
the specifier string (in this case =93municipalities=94). ZipCode=92s ge=
tValue()
method would then invoke the bean=92s getMunicipalities() method, passing=
no
specifier string. As a result, the Municipality bean would not call its
getZipCodes() method.
=20
The second string would put into the Value Object graph only the ZipCodes
and MenuItems associated with the Restaurant. The ZipCodes would not hav=
e
their Municipalities loaded and the MenuItems would not have their
Restaurant loaded.
=20
I=92ve used this method in another situation and have a small amount of
parsing code available. I=92m not at all sure how this fits in with
Middlegen, XDoclet, or even with *updating* CMP objects.
=20
I just wanted to get this documented, off my chest, and reviewed by my
peers.
=20
Thanks,
Dean Des Rosiers
=20
=20
=20
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
middlegen-user mailing list
https://lists.sourceforge.net/lists/listinfo/middlegen-user
=20
Gavin Hughes
2003-04-28 22:34:37 UTC
Permalink
Your interpretation is correct - this is how the ValueTreeBuilder works.

The tree builder does make some assumptions about how your tables are
structured (it relies on a single primary key "id" field) and about your
entity bean implementation (you need a getValueObject() method that returns
the value object for the bean - which just contains the fields for the bean).

If you can live with these restrictions it works well - I've been happily using
it for almost 2 years.

Extending it to handle more complex cases could prove difficult though.

I've done some small fixes to the code since I submitted that "patch" - see
the attachment if you're interested.

Cheers,
Gavin.


-----Original Message-----
From: Eivind Waaler [mailto:***@tihlde.org]
Sent: Tuesday, 29 April 2003 12:15 AM
To: Middlegen
Subject: Re: [Middlegen-user] Reentrant VOs


These are quite interesting ideas.

As far as I can see, these are much the same ideas that are behind the ValueTreeBuilder class in the Value Object patch:

http://sourceforge.net/tracker/?func=detail&aid=636987&group_id=36044&atid=415992

Right now I'm generating the value objects with the "light" objects returned in all relationships. This is a quite simple solution, and will only give relationships over 2 levels.

I'll look into this ValueTreeBuilder/VO graph/map feature next. As far as I can see, this will really not necesarily mean generating things in a different manner. We could ship a special edition of this utility with Middlegen together with some document describing it's use maybe? That way we'd provide the following functionality:

- Generate 2 level relationships directly.
- Provide a TreeBuilder for building structures containing more than 2 levels.
- Optionally allow "full relationship" support, meaning the user would have to make sure there are no cyclic relationships.

I think this is beginning to sound like quite a flexible solution. At least until XDoclet is able to generate without us having to worry about the reentrancy. Any comments, more ideas on this?

.eivind
Post by Dean Des Rosiers
I recently needed to compare several domain persistence layer options
to a client. I used Middlegen/XDoclet/MVCSoft to show how CMP works.
Unfortunately I needed to make my relationships uni-directional for
this to work. Naturally, this had unwanted repercussions in the rest
of my code.
I had an idea for a solution that I'd like to float. Call it a "third
way" in addition Evind's previous two. The problem seems to be
letting your VO code know when to "stop." To do this I propose a
string that I call a "specifier." This string describes the object
graph to be returned.
A Restaurant has zero or more MenuItems
A MenuItem has one and only one Restaurant
A Restaurant has zero or more ZipCodes
A ZipCode has zero or more Restaurants
A ZipCode has one or more Municipalities
A Municipality has one or more ZipCodes
A naïve implementation and deployment results in the VO reentrant
problem since both the above relationships are bi-directional. The VO
(zipCodes(municipalities), menuItems)
(zipCodes, menuItems)
Where the names are names of properties returning collections, the
parentheses denote hierarchical nesting and the commas separate a
bean's property names.
If the first string were passed in to a Restaurant's getValue() method
the method would return the matching properties as usual, but when it
called
getValue() on each member returned by Restaurant's getZipCodes() method it
would pass in whatever was between the parentheses following "zipCodes" in
the specifier string (in this case "municipalities"). ZipCode's getValue()
method would then invoke the bean's getMunicipalities() method, passing no
specifier string. As a result, the Municipality bean would not call its
getZipCodes() method.
The second string would put into the Value Object graph only the
ZipCodes and MenuItems associated with the Restaurant. The ZipCodes
would not have their Municipalities loaded and the MenuItems would not
have their Restaurant loaded.
I've used this method in another situation and have a small amount of
parsing code available. I'm not at all sure how this fits in with
Middlegen, XDoclet, or even with *updating* CMP objects.
I just wanted to get this documented, off my chest, and reviewed by my
peers.
Thanks,
Dean Des Rosiers
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
https://lists.sourceforge.net/lists/listinfo/middlegen-user
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
Eivind Waaler
2003-04-29 06:21:02 UTC
Permalink
Thanks Gavin. Good work, implementing the Value Object support was no big
deal really thanks to your excellent patch :)

I'll use your updated version, and make sure you're added to the
contributors list..

=2Eeivind
Post by Gavin Hughes
=20
Your interpretation is correct - this is how the ValueTreeBuilder works.
=20
The tree builder does make some assumptions about how your tables are=20
structured (it relies on a single primary key "id" field) and about your=
=20
Post by Gavin Hughes
entity bean implementation (you need a getValueObject() method that retur=
ns=20
Post by Gavin Hughes
the value object for the bean - which just contains the fields for the be=
an).
Post by Gavin Hughes
=20
If you can live with these restrictions it works well - I've been happily=
using
Post by Gavin Hughes
it for almost 2 years.
=20
Extending it to handle more complex cases could prove difficult though.
=20
I've done some small fixes to the code since I submitted that "patch" - s=
ee
Post by Gavin Hughes
the attachment if you're interested.
=20
Cheers,
Gavin.
=20
=20
-----Original Message-----
Sent: Tuesday, 29 April 2003 12:15 AM
To: Middlegen
Subject: Re: [Middlegen-user] Reentrant VOs
=20
=20
These are quite interesting ideas.
=20
As far as I can see, these are much the same ideas that are behind the Va=
=20
http://sourceforge.net/tracker/?func=3Ddetail&aid=3D636987&group_id=3D360=
44&atid=3D415992
Post by Gavin Hughes
=20
Right now I'm generating the value objects with the "light" objects retur=
ned in all relationships. This is a quite simple solution, and will only gi=
ve relationships over 2 levels.
Post by Gavin Hughes
=20
I'll look into this ValueTreeBuilder/VO graph/map feature next. As far as=
I can see, this will really not necesarily mean generating things in a dif=
ferent manner. We could ship a special edition of this utility with Middleg=
en together with some document describing it's use maybe? That way we'd pro=
Post by Gavin Hughes
=20
- Generate 2 level relationships directly.
- Provide a TreeBuilder for building structures containing more than 2 le=
vels.
Post by Gavin Hughes
- Optionally allow "full relationship" support, meaning the user would ha=
ve to make sure there are no cyclic relationships.
Post by Gavin Hughes
=20
I think this is beginning to sound like quite a flexible solution. At lea=
st until XDoclet is able to generate without us having to worry about the r=
eentrancy. Any comments, more ideas on this?
Post by Gavin Hughes
=20
.eivind
=20
=20
I recently needed to compare several domain persistence layer options=
=20
Post by Gavin Hughes
to a client. I used Middlegen/XDoclet/MVCSoft to show how CMP works.=
=20
Post by Gavin Hughes
Unfortunately I needed to make my relationships uni-directional for=20
this to work. Naturally, this had unwanted repercussions in the rest=
=20
Post by Gavin Hughes
of my code.
=20
I had an idea for a solution that I'd like to float. Call it a "third=
=20
Post by Gavin Hughes
way" in addition Evind's previous two. The problem seems to be=20
letting your VO code know when to "stop." To do this I propose a=20
string that I call a "specifier." This string describes the object=20
graph to be returned.
=20
A Restaurant has zero or more MenuItems
A MenuItem has one and only one Restaurant
A Restaurant has zero or more ZipCodes
A ZipCode has zero or more Restaurants
A ZipCode has one or more Municipalities
A Municipality has one or more ZipCodes
=20
A na=EFve implementation and deployment results in the VO reentrant=20
problem since both the above relationships are bi-directional. The VO=
=20
Post by Gavin Hughes
=20
(zipCodes(municipalities), menuItems)
(zipCodes, menuItems)
=20
Where the names are names of properties returning collections, the=20
parentheses denote hierarchical nesting and the commas separate a=20
bean's property names.
=20
If the first string were passed in to a Restaurant's getValue() method=
=20
Post by Gavin Hughes
the method would return the matching properties as usual, but when it=
=20
Post by Gavin Hughes
called
getValue() on each member returned by Restaurant's getZipCodes() method=
it
Post by Gavin Hughes
would pass in whatever was between the parentheses following "zipCodes"=
in
Post by Gavin Hughes
the specifier string (in this case "municipalities"). ZipCode's getVal=
ue()
Post by Gavin Hughes
method would then invoke the bean's getMunicipalities() method, passing=
no
Post by Gavin Hughes
specifier string. As a result, the Municipality bean would not call it=
s
Post by Gavin Hughes
getZipCodes() method.
=20
The second string would put into the Value Object graph only the=20
ZipCodes and MenuItems associated with the Restaurant. The ZipCodes=20
would not have their Municipalities loaded and the MenuItems would not=
=20
Post by Gavin Hughes
have their Restaurant loaded.
=20
I've used this method in another situation and have a small amount of=
=20
Post by Gavin Hughes
parsing code available. I'm not at all sure how this fits in with=20
Middlegen, XDoclet, or even with *updating* CMP objects.
=20
I just wanted to get this documented, off my chest, and reviewed by my=
=20
Post by Gavin Hughes
peers.
=20
Thanks,
Dean Des Rosiers
=20
=20
=20
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf=20
_______________________________________________
https://lists.sourceforge.net/lists/listinfo/middlegen-user
=20
=20
=20
=20
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
middlegen-user mailing list
https://lists.sourceforge.net/lists/listinfo/middlegen-user
=20
Jens Fischer
2003-05-03 18:46:02 UTC
Permalink
Hello Eivind,
Post by Eivind Waaler
Thanks Gavin. Good work, implementing the Value Object support was no big
deal really thanks to your excellent patch :)
I had a look at your CVS VO refactoring branch. Using full and light
versions for VOs solved my reentrant problems, too (didn't have the
guts to use the ValueTreeBuilder, yet). But writing business methods
against the different kinds of VOs proved to be tedious, since I have
to explicitly choose which kind of VO I want in my business method
signatures. I think it's much more useable if the full VOs would be
subclasses of the light VOs, so I can always use light VOs in my
method signatures. Here's the change needed to the entity-cmp-20.vm
file (damn, someday I really have to learn how to use CVS diff/patch!)

#if( ${plugin.valueobject} )
* @ejb.value-object
* name="${table.beanName}"
* extends="${plugin.interfacePackage}.${table.beanName}Light"
* match="*"
* instantiation="eager"
*
* @ejb.value-object
* name="${table.beanName}Light"
* match="light"
*
#end

Btw, do you know if the "instantiation" attribute does anything at
all? I found no reference to it in the XDoclet manual.

Greetings,
Jens
Eivind Waaler
2003-05-05 07:07:08 UTC
Permalink
Post by Jens Fischer
Hello Eivind,
Post by Eivind Waaler
Thanks Gavin. Good work, implementing the Value Object support was no big
deal really thanks to your excellent patch :)
I had a look at your CVS VO refactoring branch. Using full and light
versions for VOs solved my reentrant problems, too (didn't have the
guts to use the ValueTreeBuilder, yet). But writing business methods
against the different kinds of VOs proved to be tedious, since I have
to explicitly choose which kind of VO I want in my business method
signatures. I think it's much more useable if the full VOs would be
subclasses of the light VOs, so I can always use light VOs in my
method signatures. Here's the change needed to the entity-cmp-20.vm
file (damn, someday I really have to learn how to use CVS diff/patch!)
#if( ${plugin.valueobject} )
* name="${table.beanName}"
* extends="${plugin.interfacePackage}.${table.beanName}Light"
* match="*"
* instantiation="eager"
*
* name="${table.beanName}Light"
* match="light"
*
#end
Good point. I will add this asap.
Post by Jens Fischer
Btw, do you know if the "instantiation" attribute does anything at
all? I found no reference to it in the XDoclet manual.
I've been wondering about the same thing. Seems to me there is no
difference, but I'm not sure.

.eivind
Post by Jens Fischer
Greetings,
Jens
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
middlegen-user mailing list
https://lists.sourceforge.net/lists/listinfo/middlegen-user
Loading...