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