Re: newbie q #2: how to use value objects?

Michael Harm <[email protected]>
Newsgroups gmane.comp.java.ejb.middlegen.user
Message-ID <[email protected]>
Hi again Eivind.

re: VALUEOBJECT_REFACTORING_BRANCH.  I checked out that branch this 
weekend, but didn't have much luck. Maybe I bumbled something. But I 
found that if I have a table like Person that has a field homeAddress 
that is an fk into an Address table, and another field workAddress that 
  is also an fk into the Address table, it wanted to kick out two 
entries in the PersonValue object class like so:

edu.blah.blah.blah.AddressLocal Address;
edu.blah.blah.blah.AddressLocal Address;

The two problems with this are:  it generates classes for the local 
implementation and not the value for Address, meaning I can't use them 
outside of a transaction context, and also it didn't generate the name 
correctly (should be something like addressByHomeAddress and 
addressByWorkAddress)... the compiler isn't very happy with the two 
identical variable names in the above generated code. <smile>

What I'd like to see in the PersonValue class for the above would be 
more like:

edu.blah.blah.blah.AddressValue addressByHomeAddress;
edu.blah.blah.blah.AddressValue addressByWorkAddress;

So I put that aside for the time being, figuring I'd mention it later, 
and down the road check it out again. Instead, for now, I extended the 
standard, stock data object generated by ejbdoclet to include what I 
want. I honestly don't care if these object references get 
automatically populated (as they would for a 'heavy' value object); I 
just want a holder for this stuff that I can ship down the wire.  I can 
populate them myself as need be in my session beans. So I gave myself a 
crash course in xdoclet's language (shudder....), and created a 
dataobject-custom.xdt merge file in my ejbdoclet merge dir so this 
extra stuff gets tacked onto the end of the normal, vanilla data 
objects.  I'm sure this code is horrible... I had a hard time telling 
the <XDtEjbRel:forAllRelationships> tag to generate relationships just 
for the CURRENT bean, rather than all beans, so I did a really kludgey 
thing using a collection (the only way I could figure out how to pass a 
variable into the forAllRelationships scope) to sense which one I 
wanted.  It looks like this:

<XDtCollection:create name="zorkyzork" type="map"/>
<XDtCollection:put name="zorkyzork" key="owner" 
value="<XDtEjbDataObj:ejbName/>"/>
<XDtEjbRel:ifHasRelationships>
    <XDtEjbRel:forAllRelationships>
         <XDtCollection:ifContains name="zorkyzork" key="owner" 
value="<XDtEjbRel:leftEJBName/>">

         <XDtEjbRel:ifNotIsMany2Many>
         private <XDtEjbRel:rightEJBName/>Data 
_<XDtEjbRel:leftFieldName/>=null;
         public void 
<XDtMethod:setterMethod/>(<XDtEjbRel:rightEJBName/>Data 
_<XDtEjbRel:leftFieldName/>)
         {   
this._<XDtEjbRel:leftFieldName/>=_<XDtEjbRel:leftFieldName/>; }

         public <XDtEjbRel:rightEJBName/>Data <XDtMethod:getterMethod/>()
         {   return this._<XDtEjbRel:leftFieldName/>; }
         </XDtEjbRel:ifNotIsMany2Many>

         <XDtEjbRel:ifIsMany2Many>
         private java.util.Collection _<XDtEjbRel:leftFieldName/>=null;
         public void <XDtMethod:setterMethod/>(java.util.Collection 
_<XDtEjbRel:leftFieldName/>)
         {   
this._<XDtEjbRel:leftFieldName/>=_<XDtEjbRel:leftFieldName/>; }

         public java.util.Collection <XDtMethod:getterMethod/>()
         {   return this._<XDtEjbRel:leftFieldName/>; }
         </XDtEjbRel:ifIsMany2Many>

     </XDtCollection:ifContains>

         <XDtCollection:ifContains name="zorkyzork" key="owner" 
value="<XDtEjbRel:rightEJBName/>">

         <XDtEjbRel:ifNotIsOne2One>
         private java.util.Collection _<XDtEjbRel:rightFieldName/>=null;
         public void <XDtMethod:setterMethod/>(java.util.Collection 
_<XDtEjbRel:rightFieldName/>)
         {   
this._<XDtEjbRel:rightFieldName/>=_<XDtEjbRel:rightFieldName/>; }

         public java.util.Collection <XDtMethod:getterMethod/>()
         {   return this._<XDtEjbRel:rightFieldName/>; }

         </XDtEjbRel:ifNotIsOne2One>

         <XDtEjbRel:ifIsOne2One>
         private <XDtEjbRel:leftEJBName/>Data 
_<XDtEjbRel:rightFieldName/>=null;
         public void 
<XDtMethod:setterMethod/>(<XDtEjbRel:leftEJBName/>Data 
_<XDtEjbRel:rightFieldName/>)
         {   
this._<XDtEjbRel:rightFieldName/>=_<XDtEjbRel:rightFieldName/>; }

         public <XDtEjbRel:leftEJBName/>Data <XDtMethod:getterMethod/>()
         {   return this._<XDtEjbRel:rightFieldName/>; }

         </XDtEjbRel:ifIsOne2One>

     </XDtCollection:ifContains>
   </XDtEjbRel:forAllRelationships>
</XDtEjbRel:ifHasRelationships>
<XDtCollection:destroy name="zorkyzork"/>


This looks horrible, and is probably terrible xdocletmanship, but it 
generates exactly what I want: for one side of the relations (a 'Trial' 
object that has a couple fields that are fks into 'Concept') I get a 
TrialData object that has, after all the usual column fields and 
hashCode/equals stuff,

	private ConceptData _conceptByDiseaseType=null;
	public void setConceptByDiseaseType(ConceptData _conceptByDiseaseType)
         {   this._conceptByDiseaseType=_conceptByDiseaseType; }

	public ConceptData getConceptByDiseaseType()
         {   return this._conceptByDiseaseType; }

and at the other end, in 'ConceptData',

	private java.util.Collection _trialsByDiseaseType=null;
	public void setConceptByDiseaseType(java.util.Collection 
_trialsByDiseaseType)
         {   this._trialsByDiseaseType=_trialsByDiseaseType; }

	public java.util.Collection getConceptByDiseaseType()
         {   return this._trialsByDiseaseType; }

Haven't tried it for many2many relationships.. that's next. Wonder if 
it'll work.  My crufty code doesn't do the package prefix, but that's 
ok.  (Incidentally, I  got into the habit of prefixing my fields with a 
"_" because every now and then someone is naughty and creates a table 
or a column with a name that is a java keyword... like a publication 
table that has a field "abstract", which makes the java compiler really 
unhappy when used as a bare variable name).

(p.s. I wish I could tell middlegen to override the package for data 
objects... would make packaging a jar for remote, fat clients easier. 
It currently insists on putting them in the same package as the entity. 
  I can do a <packageOverride> in ejbdoclet, but the entity beans 
middlegen generates still give a full package spec to the entity bean 
package when building data objects.  any way around that?)

p.p.s.  I knew you meant "far from perfect".  Context is 99% of 
language... words are just the tent-pegs. <smile>

Now I just need to figure out how to get this "Concept" critter to be 
usable by multiple different deployments... (see my other newbie 
question).

Cheers,

-mwh


On Monday, October 20, 2003, at 11:07 PM, Eivind Waaler wrote:

> Hi Mike.
>
> I suggest you try obtaining the VALUEOBJECT_REFACTORING_BRANCH from the
> Middlegen cvs. This has been modified with support for value objects 
> and
> session bean facades. It is by far a perfect implementation of value
> object support, but might take you a step further..
>
> I'd be interested in any changes or suggestions you would have in this 
> :-)
>
> CVS info here:
> http://sourceforge.net/cvs/?group_id=36044
>
> Let me know if you have any problems..
>
> .eivind
>
> On Sat, 18 Oct 2003, Michael Harm wrote:
>
>> Hi again.
>>
>> I've been using dataobjects with middlegen/ejbdoclet (jboss 3.2.1,
>> oracle 9i), but I find that often in my session beans I'd like to be
>> able to optionally stick in references to other data objects that have
>> an fk relationship to my object.  For instance, if a Person bean has a
>> set of related Address beans, I'd like it to not only have the field 
>> in
>> AddressData for the person pk, but also a PersonData member.  When I
>> need to slap that in, I can, (thereby making a 'heavy' dataobject), or
>> optionally not (for a 'light' one).
>>
>> Value objects in xdoclet/ejbdoclet seem the thing to use.  But I'm
>> having a hard time integrating the standard middlegen stuff with that.
>> ejbdoclet wants @ejb.value-object tags in the comments for cmr  fields
>> to create the objects; otherwise I just get the column fields and
>> that's no better than what the dataobject guy gives me.  But middlegen
>> doesn't seem to want to create these tags for the cmr objects (like, 
>> in
>> the comments above the generated 'getFooByBarId' things in the entity
>> bean). I can make merged files for the column field accessors, but it
>> doesn't end up in the object reference accessors like 'getFooByBarId'.
>>   I tried hacking the velocity template to stick 'em in there, and 
>> told
>> the valueobject directive in ejbdoclet to suffix them with "Data" and
>> not "Value", and that compiles, but the resultant value objects have
>> references to Local beans, not other value objects.  In other words, 
>> my
>> AddressData guy has members like PersonLocal, not PersonData.  Which
>> means I can't use them outside a transaction context, which is the
>> whole reason I want to use value/data objects in the first place.
>>
>> So there's probably something very simple that I'm missing here.
>>
>> I understand that the whole value object thing is undergoing a major
>> refactoring, and there's an effort to replace dataobjects with
>> valueobjects entirely.  What's the status of that?  Is there a pointer
>> to info about it?  The user mailing list has only a couple references
>> to it. Is that the animal I want to be looking at?  Should I check out
>> that branch in cvs, or is it still undergoing major development?
>>
>> Or should I just try my hand at butchering xdoclet's template for data
>> objects to make it also include private fields, getters and setters 
>> for
>> referenced objects (like PersonData in the example above), and call it
>> a day?  Pretend that I never heard about value objects, and instead
>> have it generate extended data objects?
>>
>> Thanks for any info!
>>
>> cheers,
>>
>> Mike Harm
>>
>>
>>
>>
>> -------------------------------------------------------
>> This SF.net email sponsored by: Enterprise Linux Forum Conference & 
>> Expo
>> The Event For Linux Datacenter Solutions & Strategies in The 
>> Enterprise
>> Linux in the Boardroom; in the Front Office; & in the Server Room
>> http://www.enterpriselinuxforum.com
>> _______________________________________________
>> middlegen-user mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/middlegen-user
>>
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by OSDN developer relations
> Here's your chance to show off your extensive product knowledge
> We want to know what you know. Tell us and you have a chance to win 
> $100
> http://www.zoomerang.com/survey.zgi?HRPT1X3RYQNC5V4MLNSV3E54
> _______________________________________________
> middlegen-user mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/middlegen-user



-------------------------------------------------------
This SF.net email is sponsored by OSDN developer relations
Here's your chance to show off your extensive product knowledge
We want to know what you know. Tell us and you have a chance to win $100
http://www.zoomerang.com/survey.zgi?HRPT1X3RYQNC5V4MLNSV3E54
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.