Loading Composition data programatically in V7

In the Legacy version, the following code works to load the details of

MaterialRequisition requisition = dataManager.load(MaterialRequisition.class)
                .query("select e from erp$MaterialRequisition e where e.id = :reqId")
                .parameter("reqId", getItem().getMaterialRequisition().getId())
                .view("materialRequisition-view")
                .optional().orElse(null);

getItem().setPlant(requisition.getPlant());

for(MaterialRequisitionLine line : requisition.getMaterialRequisitionLine()){

    PurchaseRequisitionLine requisitionLine = metadata.create(PurchaseRequisitionLine.class);
    requisitionLine.setMaterial(line.getMaterial());
    requisitionLine.setUnitOfMeasure(line.getUnitOfMeasure());
    requisitionLine.setPurchaseRequisition(getEditedEntity());
    requisitionLine.setMaterialRequisitionLine(line);
    purchaseRequisitionLineDs.add(requisitionLine);
}

However, the following similar code in platform V7 doesn’t work, giving exception

MaterialRequisition requisition = dataManager.load(MaterialRequisition.class)
                    .query("select e from erp$MaterialRequisition e where e.id = :reqId")
                    .parameter("reqId", getEditedEntity().getMaterialRequisition().getId())
                    .view("materialRequisition-view")
                    .optional().orElse(null);

getEditedEntity().setPlant(requisition.getPlant());

for(MaterialRequisitionLine line : requisition.getMaterialRequisitionLine()){

    PurchaseRequisitionLine requisitionLine = metadata.create(PurchaseRequisitionLine.class);
    requisitionLine.setMaterial(line.getMaterial());
    requisitionLine.setUnitOfMeasure(line.getUnitOfMeasure());
    requisitionLine.setPurchaseRequisition(getEditedEntity());
    requisitionLine.setMaterialRequisitionLine(line);
    purchaseRequisitionLineDc.getMutableItems().add(requisitionLine);
} 

The exception i get is:

IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: com.myapp.entity.proc.PurchaseRequisitionLine-f62163e2-7c0a-6589-d6c9-e4f5bb1a203a [new].

Thanks for helping where and what I am missing in V7 code.

In the new API, tracking of entity changes is done by DataContext. So when you create new instances, you should merge them into the data context and use returned values in containers like in this example:

@Inject
private DataContext dataContext;
@Inject
private Metadata metadata;
@Inject
private CollectionContainer<Customer> customersDc;

private void createCustomer() {
    Customer customer = metadata.create(Customer.class);
    Customer trackedCustomer = dataContext.merge(customer);
    customersDc.getMutableItems().add(trackedCustomer);
}

To simplify code a bit, you can use DataContext.create() method which creates a new instance and merges it into the context right away:

@Inject
private DataContext dataContext;
@Inject
private CollectionContainer<Customer> customersDc;

private void createCustomer() {
    Customer trackedCustomer = dataContext.create(Customer.class);
    customersDc.getMutableItems().add(trackedCustomer);
}
1 Like