Hi Michael,

I’m aware of what ToDepPK does and the validation methods. I fact my problem is 
that I have a whole bunch of code that forwards validation from vaadin to 
cayenne back and forth and it depends on me telling it which attributes and 
relationship are mandatory.

What I can’t seem to figure out is why this particular setup which is NOT a 
mandatory relationship returns true to isMandatory() at class generation. 
Because of this unexpected behaviour, my generated classes flag that 
relationship as mandatory and trigger validation exceptions when they shouldn’t.

I was hoping that someone was familiar with the inner workings of the class 
generation templates and that I just have a typo somewhere.

Regards,
Riccardo


> On 10 Jan 2024, at 15:46, Michael Gentry <blackn...@gmail.com> wrote:
> 
> Hi Riccardo,
> 
> There is also a validateForSave() that might be easier (handles inserts and
> updates).
> 
> mrg
> 
> 
> On Wed, Jan 10, 2024 at 8:34 AM Michael Gentry <blackn...@gmail.com> wrote:
> 
>> Hi Riccardo,
>> 
>> The To Dep PK checkbox on the DbEntity isn't really intended to say "this
>> relationship is required" (that is a by-product). It is designed to assign
>> a PK from one entity to another.
>> 
>> Perhaps use a Pre-Persist Callback (ObjEntity tab) to verify the shipment
>> has a shipment number?
>> 
>> 
>> https://cayenne.apache.org/docs/4.1/cayenne-guide/#types-of-lifecycle-events
>> 
>> You could also use validateForInsert() I think, but you should also maybe
>> do a validateForUpdate() if you go down that path.
>> 
>> mrg
>> 
>> 
>> On Wed, Jan 10, 2024 at 6:50 AM Riccardo De Menna <deme...@tuorlo.net>
>> wrote:
>> 
>>> Hi Michael,
>>> 
>>>> Try deselecting the "To Dep PK" checkbox on the relationship
>>>> in SHIPMENT_NUMBER -> SHIPMENT.
>>> 
>>> I tryed both ToDep directions but they don’t seem to affect the result.
>>>> 
>>>> I can see how having that checked would make the relationship required
>>>> because it ties SHIPMENT_NUMBER's PK to SHIPMENT's PK, therefore a
>>>> SHIPMENT_NUMBER shouldn't exist without a corresponding SHIPMENT and it
>>>> sounds like you want it to be separate.
>>> 
>>> But I do expect the reverse relationship to be required… As I undrestood
>>> it, I would set ToDepPK on the SHIPMENT_NUMBER side and keep it off on the
>>> SHIPMENT side. I want to be able to generate numbers before having to link
>>> them to shipments but I also expect shipments non to exist without a number.
>>> 
>>> BTW, as I said to Nikita, if I forcefully ignore the flag and manually
>>> bypass my validation code depending on it, the ObjectContext does not seem
>>> to complain about it and does commit the save.
>>> 
>>> I assume it’s just the flag being marked as mandatory for some other side
>>> condition but I still don’t know what to use in the template as a reliable
>>> replacement.
>>> 
>>> Riccardo
>>> 
>>>> 
>>>> mrg
>>>> 
>>>> 
>>>> On Wed, Jan 10, 2024 at 12:10 AM Riccardo De Menna <deme...@tuorlo.net>
>>>> wrote:
>>>> 
>>>>> Hi Michael,
>>>>> 
>>>>> Thank you for helping. Yes… you modeled exactly what I described down
>>> to
>>>>> the delete rules. I imported your files in modeler and run class
>>> generation
>>>>> but I still get the relationship (TO_SHIP in your model) to appear as
>>>>> mandatory. Could it be an issue in class generation?
>>>>> 
>>>>> This is a little VE snippet I use in my template to output a static
>>> list
>>>>> of mandatory relationships.
>>>>> 
>>>>> #foreach( $rel in ${object.DeclaredRelationships} )
>>>>> #if (${rel.isMandatory()} && !${rel.ToMany} )
>>>>>   #set($bar =
>>>>> 
>>> $requiredRelationships.add("${stringUtils.capitalizedAsConstant($rel.Name)}_PROPERTY"))
>>>>> #end
>>>>> #end
>>>>> public static final List<String> REQUIRED_RELATIONSHIPS = List.of(
>>>>> #foreach( $rel in ${requiredRelationships} )
>>>>>   ${rel}#if(!$foreach.last),#end
>>>>> #end
>>>>> );
>>>>> 
>>>>> And contrary to what I would expect, I get this in my superclass:
>>>>> 
>>>>> public static final List<String> REQUIRED_RELATIONSHIPS = List.of(
>>>>> TO_SHIP_PROPERTY
>>>>> );
>>>>> 
>>>>> Riccardo De Menna
>>>>> 
>>>>> 
>>>>>> On 10 Jan 2024, at 01:20, Michael Gentry <blackn...@gmail.com> wrote:
>>>>>> 
>>>>>> Hi Riccardo,
>>>>>> 
>>>>>> I may have completely misunderstood your intention, but here is my
>>> first
>>>>>> cut for a model:
>>>>>> 
>>>>>> cayenne-o2o.xml:
>>>>>> <?xml version="1.0" encoding="utf-8"?>
>>>>>> <domain xmlns="http://cayenne.apache.org/schema/10/domain";
>>>>>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
>>>>>> xsi:schemaLocation="http://cayenne.apache.org/schema/10/domain
>>>>>> https://cayenne.apache.org/schema/10/domain.xsd";
>>>>>> project-version="10">
>>>>>> <map name="datamap"/>
>>>>>> </domain>
>>>>>> 
>>>>>> datamap.map.xml:
>>>>>> <?xml version="1.0" encoding="utf-8"?>
>>>>>> <data-map xmlns="http://cayenne.apache.org/schema/10/modelMap";
>>>>>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
>>>>>> xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap
>>>>>> https://cayenne.apache.org/schema/10/modelMap.xsd";
>>>>>> project-version="10">
>>>>>> <property name="defaultLockType" value="1"/>
>>>>>> <property name="defaultPackage" value="org.test"/>
>>>>>> <db-entity name="SHIPMENT">
>>>>>> <db-attribute name="ID" type="BIGINT" isPrimaryKey="true"
>>>>> isMandatory="true"
>>>>>> />
>>>>>> </db-entity>
>>>>>> <db-entity name="SHIPMENT_NUMBER">
>>>>>> <db-attribute name="ID" type="BIGINT" isPrimaryKey="true"
>>>>> isMandatory="true"
>>>>>>> 
>>>>>> <info:property xmlns:info="http://cayenne.apache.org/schema/10/info";
>>>>> name=
>>>>>> "comment" value="This ID is the same as SHIPMENT&apos;s ID."/>
>>>>>> </db-attribute>
>>>>>> <db-attribute name="NUM" type="INTEGER">
>>>>>> <info:property xmlns:info="http://cayenne.apache.org/schema/10/info";
>>>>> name=
>>>>>> "comment" value="This is the shipment number."/>
>>>>>> </db-attribute>
>>>>>> </db-entity>
>>>>>> <obj-entity name="Shipment" className="org.test.Shipment" lock-type=
>>>>>> "optimistic" dbEntityName="SHIPMENT"/>
>>>>>> <obj-entity name="ShipmentNumber" className="org.test.ShipmentNumber"
>>>>>> lock-type="optimistic" dbEntityName="SHIPMENT_NUMBER">
>>>>>> <obj-attribute name="num" type="java.lang.Integer"
>>>>> db-attribute-path="NUM"/>
>>>>>> </obj-entity>
>>>>>> <db-relationship name="toShipNum" source="SHIPMENT"
>>>>> target="SHIPMENT_NUMBER"
>>>>>>> 
>>>>>> <db-attribute-pair source="ID" target="ID"/>
>>>>>> </db-relationship>
>>>>>> <db-relationship name="toShip" source="SHIPMENT_NUMBER"
>>> target="SHIPMENT"
>>>>>> toDependentPK="true">
>>>>>> <db-attribute-pair source="ID" target="ID"/>
>>>>>> </db-relationship>
>>>>>> <obj-relationship name="toShipNum" source="Shipment"
>>>>> target="ShipmentNumber"
>>>>>> deleteRule="Cascade" db-relationship-path="toShipNum"/>
>>>>>> <obj-relationship name="toShip" source="ShipmentNumber"
>>> target="Shipment"
>>>>>> deleteRule="Deny" db-relationship-path="toShip"/>
>>>>>> </data-map>
>>>>>> 
>>>>>> Copy/Paste these files somewhere, then try loading them up into your
>>> 4.2
>>>>>> Modeler and see if it is close.
>>>>>> 
>>>>>> mrg
>>>>>> 
>>>>>> 
>>>>>> On Tue, Jan 9, 2024 at 9:54 AM Riccardo De Menna <deme...@tuorlo.net>
>>>>> wrote:
>>>>>> 
>>>>>>> Hi,
>>>>>>> 
>>>>>>> Can someone help me understand something?
>>>>>>> 
>>>>>>> I’m trying to model a one-to-one relationship between two entities
>>> but I
>>>>>>> can’t seem to get the relationship to be optional.
>>>>>>> 
>>>>>>> In my specific case I need to model an entity representing shipments
>>>>> with
>>>>>>> a postal service. Each shipment needs to have a number taken from a
>>>>>>> range/group that is pre-assigned by the postal service.
>>>>>>> 
>>>>>>> Thus I created a SHIPMENT_NUMBER entity with just an INTEGER
>>> attribute
>>>>> and
>>>>>>> then used that attribute to build the relationship with the SHIPMENT
>>>>>>> entity. Possibly with “To dep PK” as well.
>>>>>>> 
>>>>>>> I want the relationship to be optional so that I can generate
>>>>>>> SHIPMENT_NUMBER as many as I want and populate them with the numbers
>>>>>>> assigned by the postal service and only later, when the real
>>> SHIPMENT is
>>>>>>> actually needed/created, link it with the number in a one-to-one
>>>>> fashion.
>>>>>>> 
>>>>>>> I’m not sure why, but my class generated content always shows the
>>>>>>> relationship as mandatory.
>>>>>>> 
>>>>>>> Coming from the WebObjects world, I'm used to a modeler that
>>> explicitly
>>>>>>> shows checkboxes for isMandatory on relationships like with the
>>>>> attributes.
>>>>>>> Here in Cayenne it seems that optionality is implicitly determined
>>>>> based on
>>>>>>> the design.
>>>>>>> 
>>>>>>> Have I misunderstood something? Is my design flawed?
>>>>>>> 
>>>>>>> Any tip is appreciated.
>>>>>>> 
>>>>>>> Regards,
>>>>>>> Riccardo
>>>>> 
>>>>> 
>>> 
>>> 

Reply via email to