See my follow up email :) 

> On Oct 14, 2025, at 5:51 PM, Ricardo Parada <[email protected]> wrote:
> 
> Andrus,
> 
> What should I do then with the entity resolver?
> 
> I created it like you said but it’s still not being used.
> 
> Thank you
> Ricardo Parada
> 
> 
> 
> 
>> On Oct 14, 2025, at 5:33 PM, Andrus Adamchik <[email protected]> wrote:
>> 
>> 
>>> 
>>> I then save the first  data map and it throws a NullPointerException.  
>> 
>> Before save, try this to make sure entities can find each other across 
>> DataMaps:
>> 
>> EntityResolver namespace = new EntityResolver(List.of(mainMap, errorsMap));
>> 
>>> (I avoided creating data nodes and the project in this code to keep things 
>>> simple and illustrate the NullPointerException)
>> 
>> BTW, if you have a single DataNode, don't bother creating it in the model. 
>> It is much simpler and cleaner to just assign a DataSource when creating a 
>> CayenneRuntime, and Cayenne will use it to handle all DataMaps in the 
>> project.
>> 
>> Andrus
>> 
>> 
>>> On Oct 14, 2025, at 5:23 PM, Ricardo Parada <[email protected]> wrote:
>>> 
>>> Here is a very minimal test of what I am seeing.
>>> 
>>> Two data maps: Main and Errors.
>>> 
>>> I have an APP_USER DbTable in the Main data map and an APP_ERROR DbTable in 
>>> the Errors data map.
>>> 
>>> Then I have a to-many relationship and inverse to one between these two.
>>> 
>>> APP_USER <->> APP_ERROR
>>> 
>>> I then simply create the ObjEntity, ObjAttribute and ObjRelationship 
>>> objects programmatically.
>>> 
>>> I then save the first  data map and it throws a NullPointerException.  
>>> 
>>> Here is the isolated test:
>>> 
>>> (I avoided creating data nodes and the project in this code to keep things 
>>> simple and illustrate the NullPointerException)
>>> 
>>> package play.cay.utils.conversion;
>>> 
>>> import java.io.PrintWriter;
>>> import java.sql.Types;
>>> 
>>> import org.apache.cayenne.configuration.EmptyConfigurationNodeVisitor;
>>> import org.apache.cayenne.map.DataMap;
>>> import org.apache.cayenne.map.DbAttribute;
>>> import org.apache.cayenne.map.DbEntity;
>>> import org.apache.cayenne.map.DbJoin;
>>> import org.apache.cayenne.map.DbRelationship;
>>> import org.apache.cayenne.map.ObjAttribute;
>>> import org.apache.cayenne.map.ObjEntity;
>>> import org.apache.cayenne.map.ObjRelationship;
>>> import org.apache.cayenne.util.XMLEncoder;
>>> 
>>> public class DataMapTest {
>>> 
>>>  public static void main(String[] args) {
>>>      // Create DataMaps
>>>      DataMap mainMap = new DataMap("Main");
>>>      DataMap errorsMap = new DataMap("Errors");
>>> 
>>>      // -------------------- DB Entities --------------------
>>> 
>>>      // APP_USER DbEntity
>>>      DbEntity appUserDb = new DbEntity("APP_USER");
>>>      DbAttribute appUserIdDbAttr = new DbAttribute("ID", Types.INTEGER, 
>>> appUserDb);
>>>      appUserIdDbAttr.setPrimaryKey(true);
>>>      appUserDb.addAttribute(appUserIdDbAttr);
>>>      appUserDb.addAttribute(new DbAttribute("NAME", Types.VARCHAR, 
>>> appUserDb));
>>>      appUserDb.addAttribute(new DbAttribute("EMAIL", Types.VARCHAR, 
>>> appUserDb));
>>>      appUserDb.getPrimaryKeyGenerator();
>>> 
>>>      // APP_ERROR DbEntity
>>>      DbEntity appErrorDb = new DbEntity("APP_ERROR");
>>>      DbAttribute appErrorIdDbAttr = new DbAttribute("ID", Types.INTEGER, 
>>> appErrorDb);
>>>      appErrorDb.addAttribute(appErrorIdDbAttr);
>>>      appErrorDb.addAttribute(new DbAttribute("APP_USER_ID", Types.INTEGER, 
>>> appErrorDb));
>>>      appErrorDb.addAttribute(new DbAttribute("ERROR_MESSAGE", 
>>> Types.VARCHAR, appErrorDb));
>>> 
>>>      // Add DbEntities to respective maps
>>>      mainMap.addDbEntity(appUserDb);
>>>      errorsMap.addDbEntity(appErrorDb);
>>> 
>>>      // -------------------- DB Relationships --------------------
>>> 
>>>      // APP_ERROR -> APP_USER (to-one)
>>>      DbRelationship toUserRel = new DbRelationship("appUser");
>>>      toUserRel.setSourceEntity(appErrorDb);
>>>      toUserRel.setTargetEntityName(appUserDb);
>>>      toUserRel.setToMany(false);
>>>      toUserRel.addJoin(new DbJoin(toUserRel, "APP_USER_ID", "ID"));
>>>      appErrorDb.addRelationship(toUserRel);
>>> 
>>>      // APP_USER ->> APP_ERROR (to-many)
>>>      DbRelationship errorsRel = new DbRelationship("errors");
>>>      errorsRel.setSourceEntity(appUserDb);
>>>      errorsRel.setTargetEntityName(appErrorDb);
>>>      errorsRel.setToMany(true);
>>>      errorsRel.addJoin(new DbJoin(errorsRel, "ID", "APP_USER_ID"));
>>>      appUserDb.addRelationship(errorsRel);
>>> 
>>>      // -------------------- ObjEntities --------------------
>>> 
>>>      // APP_USER ObjEntity
>>>      ObjEntity appUserObj = new ObjEntity("AppUser");
>>>      appUserObj.setDbEntity(appUserDb);
>>>      appUserObj.addAttribute(new ObjAttribute("id", "java.lang.Integer", 
>>> appUserObj));
>>>      appUserObj.addAttribute(new ObjAttribute("name", "java.lang.String", 
>>> appUserObj));
>>>      appUserObj.addAttribute(new ObjAttribute("email", "java.lang.String", 
>>> appUserObj));
>>> 
>>>      // APP_ERROR ObjEntity
>>>      ObjEntity appErrorObj = new ObjEntity("AppError");
>>>      appErrorObj.setDbEntity(appErrorDb);
>>>      appErrorObj.addAttribute(new ObjAttribute("id", "java.lang.Integer", 
>>> appErrorObj));
>>>      appErrorObj.addAttribute(new ObjAttribute("errorMessage", 
>>> "java.lang.String", appErrorObj));
>>> 
>>>      // Add ObjEntities to respective maps
>>>      mainMap.addObjEntity(appUserObj);
>>>      errorsMap.addObjEntity(appErrorObj);
>>> 
>>>      // -------------------- ObjRelationships --------------------
>>> 
>>>      // AppError → AppUser (to-one)
>>>      ObjRelationship appUserRel = new ObjRelationship("appUser");
>>>      appUserRel.setSourceEntity(appErrorObj);
>>>      appUserRel.setTargetEntityName(appUserObj); // sets target name
>>>      appUserRel.setDbRelationshipPath("appUser");
>>>      appErrorObj.addRelationship(appUserRel);
>>> 
>>>      // AppUser → AppError (to-many)
>>>      ObjRelationship errorsRelObj = new ObjRelationship("errors");
>>>      errorsRelObj.setSourceEntity(appUserObj);
>>>      errorsRelObj.setTargetEntityName(appErrorObj); // sets target name
>>>      errorsRelObj.setDbRelationshipPath("errors");
>>>      appUserObj.addRelationship(errorsRelObj);
>>> 
>>>      PrintWriter stdout = new PrintWriter(System.out, true);
>>>      XMLEncoder encoder = new XMLEncoder(stdout, "\t", "11");
>>>      EmptyConfigurationNodeVisitor visitor = new 
>>> EmptyConfigurationNodeVisitor();
>>> 
>>>      stdout.println(mainMap.getName());
>>>      stdout.println();
>>>      encoder.nested(mainMap, visitor);
>>> 
>>>      stdout.println();
>>>      stdout.println();
>>> 
>>>      stdout.println(errorsMap.getName());
>>>      stdout.println();
>>>      encoder.nested(errorsMap, visitor);
>>> 
>>>  }
>>> }
>>> 
>>> 
>>> 
>>>> 
>>>>> On Oct 14, 2025, at 3:29 PM, Ricardo Parada <[email protected]> wrote:
>>>> 
>>>> Hello,
>>>> 
>>>> I wrote a converter to convert our eomodels from EOF to 
>>>> Cayenne-project.xml and data maps .map.xml
>>>> 
>>>> So far so good. However, I seem to be running into a problem for cross 
>>>> data map relationships.
>>>> 
>>>> I’m using 5.0-M1.
>>>> 
>>>> When I’m creating the ObjRelationship I call:
>>>> 
>>>> objRel.setTargetEntityName(targetObjEntity);
>>>> 
>>>> If I then call objRel.getTargetEntityName() it returns the correct target 
>>>> entity name.  
>>>> 
>>>> However, if I call objRel.getTargetEntity() it returns null.
>>>> 
>>>> I debugged the code and I can see that getTargetEntity() is looking for 
>>>> the target entity name in the data map corresponding to the source 
>>>> ObjEntity. And it does not find it and returns null for that reason.
>>>> 
>>>> As a result of that, when I call encodeAsXML() on objRel I see that the 
>>>> XML is missing the target attribute in the obj-relationship xml tag.
>>>> 
>>>> Is this a bug in 5.0-M1 or am I missing something when creating my 
>>>> ObjRelationship programmatically.
>>>> 
>>>> I could put all eomodels that have cross eomodel relationships into the 
>>>> same data map to avoid this problem.
>>>> 
>>>> But when I create it in Cayenne Modeler 4.3.3 it seems to work. I see the 
>>>> obj-relationship in the XML have target correctly set.
>>>> 
>>>> Thank you all in advance.
>>>> Ricardo Parada
>> 

Reply via email to