Working programmatically with non-commited composite entities

Hi, I have been trying to do something quite simple but can’t get it to work… kind help would be much appreciated!

So, I have 4 entities, set up as follows:

  1. Concert
  2. ConcertPerson
  3. ConcertUnit
  4. ConcertPersonConcertUnit
  • 2), 3), 4) are compositions of 1).
    1. ConcertPersonConcertUnit has many_to_one association with 2) and 3) respectively (uni-directional)

I want to build a Concert Edit Screen which:
A) lets me add ConcertUnits and ConcertPersons (easy to do via the gui table create actions)
B) programmatically creates a new Cpcu for each combination of new ConcertUnit and ConcertPerson (this is where I’m having trouble).

My edit screen is setup with one Datasource for entity 1), and 3 NestedDatasources for entities 2) 3) 4).
In the layout I have 3 tables for the 3 NestedDatasources.

Here is my code to implement functionality B)


@Override
    public void init(Map<String, Object> params) {

	//Catch new ConcertPerson created
	concertPersonDs.addCollectionChangeListener(event -> {  
      ???  if (event.getOperation() == CollectionDatasource.Operation.ADD) {addUnitsToNewPerson(event);}
	});
        
      //Catch new ConcertUnit created
        concertUnitDs.addCollectionChangeListener(event -> {
        ??if (event.getOperation() == CollectionDatasource.Operation.ADD) {addNewUnitsToPersons(event);}
	}); 
}
private void addUnitsToNewPerson(CollectionChangeEvent<ConcertPerson, UUID> event) {	
		List<ConcertPerson> concertPersonList = event.getItems();
		Concert concert = getItem();
		List<ConcertUnit> concertUnitList = concert.getConcertUnit();
		
  	   if (concertUnitList != null){
	  	   for (ConcertPerson concertPerson : concertPersonList){
	  		   for (ConcertUnit concertUnit : concertUnitList){
	  			   ConcertPersonConcertUnit cpcu= metadata.create(ConcertPersonConcertUnit .class);
	  			   cpcu.setConcertPerson(concertPerson);
	  			   cpcu.setConcertUnit(concertUnit);
??????????concert.getCpcu().add(cpcu);
	  		   }   
	  	   }   
  	   } 
}
//Similar code for "addNewUnitsToPersons"

Now I have issues understanding the following points:

  • When I create a new concert from the Concert Browse screen, and then add a new ConcertUnit and ConcertPerson in the Concert Edit screen without first committing the Concert by pressing “OK”, I get a NullException on “concert.getCpcu().add(cpu);” Why is that? I thought that because ConcertUnit, ConcertPerson, and ConcertPersonConcertUnit where all set as combinations of Concert, I could create them without having to commit the Concert first.

  • If I commit the concert first, then open the Edit screen again, and create a new ConcertUnit and Concertperson, a Cpcu is succesfully created (I can see it in the table), but not saved upon committing by clicking “OK”. At least, it does not appear in the table when I open the screen again. Why is that? (I.e., is it because the concert is now in detached state? or is it because the change in the concert is not automatically added to the commitContext?)

  • If I try to force to save changes using “dataManager.commit(concert);” I get “SQLIntegrityConstraintViolationException: integrity constraint violation: unique constraint or index violation; SYS_PK_10974 table: TESTCOMPO_CONCERT_PERSON”. What is the reason for this?
    Note that ideally, I would like to save the changes only when I click “OK”.

Apologies for the long post… thank you in advance.
Best regards,

Matthis

Hi Matthis,

Try to change your code to the following:


for (ConcertUnit concertUnit : concertUnitList){
    ConcertPersonConcertUnit cpcu= metadata.create(ConcertPersonConcertUnit .class);
    cpcu.setConcertPerson(concertPerson);
    cpcu.setConcertUnit(concertUnit);
    cpcu.setConcert(concert); // reference to Concert

    cpcuDs.addItem(cpcu); // add the new entity to the ConcertPersonConcertUnit nested datasource
} 

It should be enough. If not, please extract these entities and the screen to a small demo project and attach here - I will take a closer look.

Thank you for your help and apologies for the late reply.
This worked great!