Асинхронный обратный вызов - gwt - PullRequest
1 голос
/ 16 марта 2010

Я использую gwt и postgres для своего проекта. На внешнем интерфейсе у меня есть несколько виджетов, данные которых я пытаюсь сохранить в таблицах на заднем плане, когда нажимаю кнопку «сохранить проект» (это также принимает имя для созданного проекта).

В части асинхронного обратного вызова я устанавливаю более одной таблицы. Но это не отправка данных должным образом. Я получаю следующую ошибку:

org.postgresql.util.PSQLException: ERROR: insert or update on table "entitytype" violates foreign key constraint "entitytype_pname_fkey"
  Detail: Key (pname)=(Project Name) is not present in table "project".

Но когда я делаю оператор выбора в таблице проекта, я вижу, что имя проекта присутствует.

Вот как выглядит часть обратного вызова:

        oksave.addClickHandler(new ClickHandler(){
                            @Override
                            public void onClick(ClickEvent event) {
                                if(erasync == null)
                                    erasync = GWT.create(EntityRelationService.class);
                                AsyncCallback<Void> callback = new AsyncCallback<Void>(){
                                    @Override
                                    public void onFailure(Throwable caught) {
                                        }

                                    @Override
                                    public void onSuccess(Void result){  }                          
                        };      
    erasync.setProjects(projectname, callback);

                                for(int i = 0; i < boundaryPanel.getWidgetCount(); i++){

                                    top = new Integer(boundaryPanel.getWidget(i).getAbsoluteTop()).toString();
                                    left = new Integer(boundaryPanel.getWidget(i).getAbsoluteLeft()).toString();
                                    if(widgetTitle.startsWith("ATTR")){
                                        type = "regular";

                                            erasync.setEntityAttribute(name1, name, type, top, left, projectname, callback);
                                        }   else{
erasync.setEntityType(name, top, left, projectname, callback);
}                           
                                    }
    }

Вопрос:

  1. Неправильно ли устанавливать более одного в асинхронном обратном вызове, когда все другие таблицы зависят от конкретной таблицы?
  2. когда я говорю, что setProjects в вышеприведенном коде сначала не завершается, а затем переходит к следующему?

Пожалуйста, любые отзывы будут с благодарностью.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 16 марта 2010

С этим ограничением внешнего ключа вы должны убедиться, что erasync.setProjects (...) завершен, прежде чем вставлять оставшуюся часть.

Я предлагаю сделать магию erasync.setEntityAttribute(...) в (или из) обратном вызове при успешном выполнении вместо того, чтобы прыгать прямо к нему.

0 голосов
/ 17 марта 2010

Вы запускаете несколько запросов, в которых (исходя из сообщения об ошибке) действительно должен быть вызван последовательно.

Каждый раз, когда вы звоните более чем на один вызов RPC; попытайтесь подумать, что вы должны иметь возможность переставить их в любом порядке (потому что это практически все, что происходит на самом деле, потому что они асинхронные) ... Если запускать их в обратном порядке не имеет смысла; Вы не можете запустить их последовательно!

Два способа решить вашу проблему:

Вложение:

    service.callFirst(someData, new AsyncCallback<Void> callback = new AsyncCallback<Void>(){
        @Override
        public void onFailure(Throwable caught) {/*Handle errors*/}
        @Override
        public void onSuccess(Void result){
            service.callSecond(someOtherData, new AsyncCallback<Void> callback = new AsyncCallback<Void>(){ 
                /* onSuccess and onFailure for second callback here */ 
            });
        }                       
    });

Или создание одного вызова службы, который выполняет оба действия (рекомендуется):

    service.callFirstAndSecond(someData, someOtherData, new AsyncCallback<Void> callback = new AsyncCallback<Void>(){
        @Override
        public void onFailure(Throwable caught) {/*Handle errors*/}
        @Override
        public void onSuccess(Void result){
            /* Handle success */
        }                       
    });

Второй вариант, скорее всего, будет гораздо менее запутанным, поскольку несколько вложенных асинхронных обратных вызовов быстро растут и приводят к путанице, также вы делаете только один запрос.

0 голосов
/ 17 марта 2010

В силу характера асинхронности не предполагайте, что метод setProjects(...) будет вызван на сервере раньше, чем setEntityAttribute или setEntityType.

Лично я предпочитаю иметь класс Project, который содержит всю необходимую информацию, например:

public class Project{  
      private String projectName;  
      private List attributes = new ArrayList();  
      .. other properties  

  // Getter & Setter methods  
}

Затем отправьте на сервер в одну поездку:

Project project = new Project();  
project.setProjectName(..);  
// Set other properties  
erasync.saveProjects(project, callback);
...