Liferay模型监听器 - 在更新处理程序循环之后

时间:2016-06-17 09:38:44

标签: liferay listener

我在Liferay 6.2 GA6中为DLFileEntry创建了自定义模型侦听器。但是,即使未对DLFileEntry进行任何更改,也会重复调用onAfterUpdate方法。

让我来描述一下情况:

  1. 通过Liferay中的内容管理更改文件条目
  2. 触发onAfterUpdate方法(这没关系)
  3. onAfterUpdate方法会一次又一次地被触发 - 即使此条目没有更新
  4. 当(意外)更新事件发生时,我已经转储了堆栈跟踪。看起来onAfterUpdateincrementViewCounter(..)方法触发,由BufferedIncrementRunnable

    触发
    java.lang.Exception: Stack trace
            at java.lang.Thread.dumpStack(Thread.java:1365)
            at eu.package.hook.model.listener.DLFileEntryModelListener.onAfterUpdate(DLFileEntryModelListener.java:63)
            at eu.package.hook.model.listener.DLFileEntryModelListener.onAfterUpdate(DLFileEntryModelListener.java:32)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:606)
            at com.liferay.portal.kernel.bean.ClassLoaderBeanHandler.invoke(ClassLoaderBeanHandler.java:67)
            at com.sun.proxy.$Proxy865.onAfterUpdate(Unknown Source)
            at com.liferay.portal.service.persistence.impl.BasePersistenceImpl.update(BasePersistenceImpl.java:340)
            at com.liferay.portlet.documentlibrary.service.impl.DLFileEntryLocalServiceImpl.incrementViewCounter(DLFileEntryLocalServiceImpl.java:1450)
            at sun.reflect.GeneratedMethodAccessor2034.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:606)
            at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
            at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
            at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
            at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
            at com.liferay.portal.increment.BufferedIncreasableEntry.proceed(BufferedIncreasableEntry.java:48)
            at com.liferay.portal.increment.BufferedIncrementRunnable.run(BufferedIncrementRunnable.java:65)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
            at java.lang.Thread.run(Thread.java:745)
    

    我已经阅读了关于portal.properties docs page中的bufferend增量的文档。建议不要禁用此功能。

    我还考虑过检查模型侦听器方法中是否对DLFileEntry对象进行了任何相关更改。我只是想检查一下,当onAfterUpdate方法触发incrementViewCounter方法时,是否有任何可以绕过private void createMessage(DLFileEntry model, String create) { JSONObject jsonObject = JSONFactoryUtil.createJSONObject(); jsonObject.put("action", create); jsonObject.put("id", model.getFileEntryId()); MessageBusUtil.sendMessage(SUPIN_MESSAGE_LISTENER_DESTINATION, jsonObject); } @Override public void onAfterUpdate(DLFileEntry model) throws ModelListenerException { if (LOG.isTraceEnabled()) { URL[] urls = ((URLClassLoader) (Thread.currentThread().getContextClassLoader())).getURLs(); LOG.trace("Current thread classpath is: " + StringUtils.join(urls, ",")); } LogMF.info(LOG, "File entry on update event - id {0}" , new Object[]{model.getFileEntryId()}); Thread.dumpStack(); createMessage(model, UPDATE); } 方法的配置。

    感谢任何帮助。

    更新:

    更新后的方法:

    private void createOrUpdate(DLFileEntry model, String createOrUpdate) {
        try {
            initPermissionChecker(model);
    
            LOG.info("Document " + model.getFileEntryId() + " " + createOrUpdate + "d in Liferay. Creating entry in Safe.");
            long documentInSafe;
            if (UPDATE.equalsIgnoreCase(createOrUpdate)) {
                documentInSafe = (long) model.getExpandoBridge().getAttribute(EXPANDO_SAFE_DOCUMENT_ID);
                if (documentInSafe > 0) {
                    safeClient.updateDocumentInSafe(model);
                } else {
                    documentInSafe = safeClient.createDocumentInSafe(model);
                }
            } else {
                documentInSafe = safeClient.createDocumentInSafe(model);
            }
            LOG.info("Document " + createOrUpdate +"d successfully with id " + documentInSafe);
            saveSafeIDToExpando(model, documentInSafe);
        } catch (Exception e) {
            LOG.error("Unable to safe ID of document in Safe", e);
        }
    }
    
    private void saveSafeIDToExpando(DLFileEntry model, long documentInSafe) throws SystemException {
        try {
            ExpandoTable table = ExpandoTableLocalServiceUtil.getDefaultTable(model.getCompanyId(), DLFileEntry.class.getName());
            ExpandoColumn column = ExpandoColumnLocalServiceUtil.getColumn(table.getTableId(), EXPANDO_SAFE_DOCUMENT_ID);
            ExpandoValueLocalServiceUtil.addValue(model.getCompanyId(), table.getTableId(), column.getColumnId(), model.getClassPK(), String.valueOf(documentInSafe));
            LOG.info("ID of document in Safe updated in expando attribute");
        } catch (PortalException e) {
            LOG.error("Unable to save Safe document ID in expando." , e);
            ;
        }
    }
    
    private void initPermissionChecker(DLFileEntry model) throws Exception {
        User safeAdminUser = UserLocalServiceUtil.getUserByScreenName(model.getCompanyId(), SAFE_ADMIN_SCREEN_NAME);
        PermissionChecker permissionChecher = PermissionCheckerFactoryUtil.create(safeAdminUser);
        PermissionThreadLocal.setPermissionChecker(permissionChecher);
        PrincipalThreadLocal.setName(safeAdminUser.getUserId());
        CompanyThreadLocal.setCompanyId(model.getCompanyId());
        LOG.info("Permission checker successfully initialized.");
    }
    

    以下是更新操作后执行on的消息侦听器(消息总线):

    var socket = io.connect('http://localhost:3000', {'reconnection': false});
    

1 个答案:

答案 0 :(得分:0)

我建议这样做,但我不确定它能否解决你的问题。

我在AfterUpdate上更改了自己方法的主体。

使用TransactionCommitCallbackRegistryUtil,您可以从后续的createMessage逻辑中分离模型更新请求。

public void onAfterUpdate(DLFileEntry model) throws ModelListenerException {

    TransactionCommitCallbackRegistryUtil.registerCallback(new Callable() {

         @Override
         public Void call() throws Exception {
              createMessage(model, UPDATE);
    }
}