RequestFactoryEditorDriver doesn't save full g

2019-08-15 05:09发布

Could you guys please help me find where I made a mistake ?

I switched from SimpleBeanEditorDriver to RequestFactoryEditorDriver and my code no longer saves full graph even though with() method is called. But it correctly loads full graph in the constructor.

Could it be caused by circular reference between OrganizationProxy and PersonProxy ? I don't know what else to think :( It worked with SimpleBeanEditorDriver though.

Below is my client code. Let me know if you want me to add sources of proxies to this question (or you can see them here).

public class NewOrderView extends Composite
{
    interface Binder extends UiBinder<Widget, NewOrderView> {}
    private static Binder uiBinder = GWT.create(Binder.class);

    interface Driver extends RequestFactoryEditorDriver<OrganizationProxy, OrganizationEditor> {}
    Driver driver = GWT.create(Driver.class);

    @UiField
    Button save;

    @UiField
    OrganizationEditor orgEditor;

    AdminRequestFactory requestFactory;
    AdminRequestFactory.OrderRequestContext requestContext;

    OrganizationProxy organization;

    public NewOrderView()
    {
        initWidget(uiBinder.createAndBindUi(this));

        requestFactory = createFactory();
        requestContext = requestFactory.contextOrder();
        driver.initialize(requestFactory, orgEditor);

        String[] paths = driver.getPaths();
        createFactory().contextOrder().findOrganizationById(1).with(paths).fire(new Receiver<OrganizationProxy>()
        {
            @Override
            public void onSuccess(OrganizationProxy response)
            {
                if (response == null)
                {
                    organization = requestContext.create(OrganizationProxy.class);
                    organization.setContactPerson(requestContext.create(PersonProxy.class));
                } else
                    organization = requestContext.edit(response);

                driver.edit(organization, requestContext);
            }

            @Override
            public void onFailure(ServerFailure error)
            {
                createConfirmationDialogBox(error.getMessage()).center();
            }
        });
    }

    private static AdminRequestFactory createFactory()
    {
        AdminRequestFactory factory = GWT.create(AdminRequestFactory.class);
        factory.initialize(new SimpleEventBus());
        return factory;
    }

    @UiHandler("save")
    void buttonClick(ClickEvent e)
    {
        e.stopPropagation();
        save.setEnabled(false);

        try
        {
            AdminRequestFactory.OrderRequestContext ctx = (AdminRequestFactory.OrderRequestContext) driver.flush();
            if (!driver.hasErrors())
            {
                // Link to each other
                PersonProxy contactPerson = organization.getContactPerson();
                contactPerson.setOrganization(organization);

                String[] paths = driver.getPaths();
                ctx.saveOrganization(organization).with(paths).fire(new Receiver<Void>()
                {
                    @Override
                    public void onSuccess(Void arg0)
                    {
                        createConfirmationDialogBox("Saved!").center();
                    }

                    @Override
                    public void onFailure(ServerFailure error)
                    {
                        createConfirmationDialogBox(error.getMessage()).center();
                    }
                });
            }
        } finally
        {
            save.setEnabled(true);
        }
    }
}

2条回答
虎瘦雄心在
2楼-- · 2019-08-15 05:59

It took me some time to realize that the problem was the composite id of Person entity.

Below is the code snippet of PojoLocator that is used by my proxy entities.

public class PojoLocator extends Locator<DatastoreObject, Long>
{
    @Override
    public DatastoreObject find(Class<? extends DatastoreObject> clazz, Long id)
    {
    }

    @Override
    public Long getId(DatastoreObject domainObject)
    {
    }
}

In order to fetch child entity from DataStore you need to have id of a parent class. In order to achieve that I switched "ID class" for Locator<> to String which represents textual form of Objectify's Key<> class.

Here is how to looks now:

public class PojoLocator extends Locator<DatastoreObject, String>
{
    @Override
    public DatastoreObject find(Class<? extends DatastoreObject> clazz, String id)
    {
        Key<DatastoreObject> key = Key.create(id);
        return ofy.load(key);
    }

    @Override
    public String getId(DatastoreObject domainObject)
    {
        if (domainObject.getId() != null)
        {
            Key<DatastoreObject> key = ofy.fact().getKey(domainObject);
            return key.getString();
        } else
            return null;
    }
}

Please note that your implementation may slightly differ because I'm using Objectify4.

查看更多
做自己的国王
3楼-- · 2019-08-15 06:12

with() is only used for retrieval of information, so your with() use with a void return type is useless (but harmless).

Whether a full graph is persisted is entirely up to your server-side code, which is intimately bound to your persistence API (JPA, JDO, etc.)

First, check that the Organization object you receive in your save() method on the server-side is correctly populated. If it's not the case, check your Locators (and/or static findXxx methods) ; otherwise, check your save() method's code.

Judging from the code above, I can't see a reason why it wouldn't work.

查看更多
登录 后发表回答