首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GWT对错误对象的RequestFactory调用设置器

GWT对错误对象的RequestFactory调用设置器
EN

Stack Overflow用户
提问于 2014-08-29 20:51:24
回答 2查看 122关注 0票数 0

首先,它不是错误的对象,但它不是正确的参考,因为我已经诊断出了问题。

我有一个编辑器,我正在编辑一个对象,其中包含另一个包含更多bean的列表编辑器。

我有一个TagCollectionProxy,它包含一个TagProxy对象的列表。当我用附加的List对象保存TagCollectionProxy时,就会出现问题。我的实体定位器正在数据库中查找对象并设置值,但是我没有对该对象的引用。这是新的,我不知道为什么现在会发生这种情况。

当我调用对象上的保存时,此调试消息。我已经在setValue上的标记类中放置了一条消息,您可以看到我在域实体上设置了正确的值。身份匹配。这个问题出现在我的dao类中的下一个保存消息(TagCollection)中。我正在对实体进行迭代并打印值,但该实体的值没有更改。

代码语言:javascript
复制
2014-08-29T15:34:15.912-0500|INFO: Setting value Tag2asdfasdfasdfasdf for id 294 Reference cpbx.rialto.dms.Tag@1135696
2014-08-29T15:34:15.944-0500|INFO: Tag name => asdfasdf Tag value => Tag2 id => 294 ref => cpbx.rialto.dms.Tag@1893889
2014-08-29T15:34:15.944-0500|INFO: Id of tag is 294

提前谢谢你的帮助,我马上就脱发了。

这是我保存对象的活动。注意,我正在保存包含标记列表的TagCollectionProxy。

代码语言:javascript
复制
public class TagCollectionEditActivity extends AbstractActivity<TagCollectionEditView> implements
        TagCollectionEditView.Presenter {



    private Receiver<Long> saveReceiver = new Receiver<Long>() {
        @Override
        public void onSuccess(Long response) {
            logger.info("saved tagCollection with id of " + response);
            clientFactory.getPlaceController().goTo(new TagCollectionsPlace());
        }

        public void onConstraintViolation(Set<ConstraintViolation<?>> violations) {

            for (ConstraintViolation<?> violation : violations) {
                logger.warning(violation.getMessage());
            }
            getDisplay().getEditorDriver().setConstraintViolations(violations);
        }

        public void onFailure(ServerFailure failure) {
            logger.log(Level.SEVERE, "Failed to save tag collection " + failure.getMessage());
            getDisplay().showError(failure);
        }
    };

    private static final Logger logger = Logger.getLogger(TagCollectionEditActivity.class.getName());

    private IClientFactory clientFactory;

    private TagCollectionDaoRequest editContext = null;

    public TagCollectionEditActivity(IClientFactory clientFactory) {
        super(new TagCollectionEditView(clientFactory.getResources(), clientFactory.getEventBus()));
        this.clientFactory = clientFactory;
    }

    @Override
    protected void bindToView() {
        getDisplay().setPresenter(this);
        final TagCollectionEditPlace place = (TagCollectionEditPlace) getPlace();
        Long tagCollectionId = place.getTagCollectionId();

        if (tagCollectionId == null) {
            createTagCollection();
        } else {
            findCollection(tagCollectionId);
        }
    }

    private void findCollection(Long tagCollectionId) {
        clientFactory.tagCollectionRequest().find(tagCollectionId).with(getEntityProperties())
                .fire(new Receiver<TagCollectionProxy>() {

                    @Override
                    public void onSuccess(TagCollectionProxy tagCollection) {
                        editContext = clientFactory.tagCollectionRequest();
                        editContext.save(tagCollection).with(getDisplay().getEditorDriver().getPaths()).to(saveReceiver);
                        getDisplay().getEditorDriver().edit(tagCollection, editContext);
                        GWT.log("Context is " + editContext.hashCode());
                    }
                });
    }

    private void createTagCollection() {
        editContext = clientFactory.tagCollectionRequest();
        TagCollectionProxy tagCollection = editContext.create(TagCollectionProxy.class);
        editContext.save(tagCollection).with(getDisplay().getEditorDriver().getPaths()).to(saveReceiver);
        tagCollection.setTags(new ArrayList<TagProxy>());
        getDisplay().getEditorDriver().edit(tagCollection, editContext);
    }

    @Override
    public void onSave() {
        RequestContext context = getDisplay().getEditorDriver().flush();
        context.fire();
    }   

    public String[] getEntityProperties() {
        return new String[] { "tags", "deviceFamily" };
    }

    @Override
    public void onCancel() {
        clientFactory.getPlaceController().goTo(new TagCollectionsPlace());
    }
}

这里是我定义DomainEntityLocator的标记集合代理

代码语言:javascript
复制
@ProxyFor(value = TagCollection.class, locator = DomainEntityLocator.class)
public interface TagCollectionProxy extends DomainEntityProxy {

    public List<TagProxy> getTags();

    public void setTags(List<TagProxy> tags);

    public DeviceFamilyProxy getDeviceFamily();

    public void setDeviceFamily(DeviceFamilyProxy deviceFamily);

}

这里是我的定位器,它使用数据库来使用JPA entityManager查找对象。

代码语言:javascript
复制
public class DomainEntityLocator extends Locator<DomainEntity, Long> {

    private static EntityManager em = null;

    static {
        Context initCtx;
        try {
            initCtx = new InitialContext();
            // perform JNDI lookup to obtain container-managed entity manager
            em = (javax.persistence.EntityManager) initCtx.lookup("java:comp/env/persistence/DomainEntityManager");

        } catch (NamingException e) {
            throw new RuntimeException("Unable to get the domain entity manager");
        }
    }

    public DomainEntityLocator() {
    }

    @Override
    public DomainEntity create(Class<? extends DomainEntity> clazz) {
        try {
            return clazz.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public DomainEntity find(Class<? extends DomainEntity> clazz, Long id) {
        return em.find(clazz, id);
    }

    @Override
    public Class<DomainEntity> getDomainType() {
        return DomainEntity.class;
    }

    @Override
    public Long getId(DomainEntity domainObject) {
        return domainObject.getId();
    }

    @Override
    public Class<Long> getIdType() {
        return Long.class;
    }

    @Override
    public Object getVersion(DomainEntity domainObject) {
        return 0;
    }
}

更新

经过一些调查后,我意识到服务器端的JPA是我的问题的罪魁祸首。我得出的结论是,DomainEntityLocator正在获取实体,而不是将其包装在事务中。因此,DomainEntityLocator#find()方法将检索实体,而ServiceLayer将修改实体上的值。我遇到的问题是,find方法没有包装在事务中,而且由于我要检索的实体管理器没有被管理,所以实体管理器没有刷新更改。因此,我看不到该值的更新。

关于主题问题#2

是否存在将事务管理添加到实体定位器的通用模式,以便在请求工厂调用setter之后将对象持久化。我以前使用一个简单的servlet过滤器来完成这个任务,但是我正在进行的项目需要java来维护这种功能。我不能使DomainEntityLocator成为一个无状态bean,因为ServiceLayer将查找它的方式。是否最好扩展RequestFactoryServlet并将doPost封装在一个转接中?这似乎是最合乎逻辑的想法。有什么建议吗?

再次感谢托马斯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-01 09:04:33

在服务器端,RequestFactory将使用您的定位器按其ID加载每个对象,因此将加载TagCollection (以及它的Tag列表),每个Tag也将使用DomainEntityLocator加载(假设它们在@ProxyFor中是这样声明的)。

将在定位器返回的对象上调用设置器,而不是TagCollectiongetTags列表中的对象。

你必须确保它们是相同的实例。

对于JPA,这意味着使用“公开会话视图”(也称为“每个请求的会话”)模式。JPA会话使用缓存,因此在整个HTTP请求中共享相同的会话将确保无论何时从TagCollection加载或直接通过ID加载相同的TagCollection实例。

票数 2
EN

Stack Overflow用户

发布于 2014-09-02 15:04:14

这里是我为解决EJB和RequestFactory.的问题所做的工作。

在发现RequestFactory方法没有包装在实体管理器的事务中之后,我想到了两个选择。其一,我可以向实体定位器的查找和创建方法中添加一个UserTransaction,但是我决定将整个请求包装在一个事务中,这对我的情况很好,因为我的请求工厂方法应该总是在事务中。

我扩展了请求工厂servlet,并将UserTransaction添加到doPost中。

代码语言:javascript
复制
@WebServlet("/rf/secure/dao")
public class DmsRequestFactoryServlet extends RequestFactoryServlet {

    private static final long serialVersionUID = -521670028586842819L;

    private static final Logger logger = Logger.getLogger(DmsRequestFactoryServlet.class.getName());

    @Resource
    private UserTransaction tx;


    public static class SimpleExceptionHandler implements ExceptionHandler {

        @Override
        public ServerFailure createServerFailure(Throwable throwable) {
            logger.log(Level.SEVERE, "Unable to complete request", throwable);

            return new ServerFailure("Server Error: " + (throwable == null ? null : throwable.getMessage()), throwable
                    .getClass().getName(), ExceptionUtils.getStackTrace(throwable), true);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException,
            ServletException {
        try {
            tx.begin();
            super.doPost(request, response);
            tx.commit();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Failed request ", e);
        }
    }

    public DmsRequestFactoryServlet() {
        super(new SimpleExceptionHandler());
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25576067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档