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'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 >>>>> >>>>> >>> >>>