我在Liferay 6.2 GA6中为DLFileEntry创建了自定义模型侦听器。但是,即使未对DLFileEntry进行任何更改,也会重复调用onAfterUpdate方法。
让我来描述一下情况:
onAfterUpdate
方法(这没关系)onAfterUpdate
方法会一次又一次地被触发 - 即使此条目没有更新当(意外)更新事件发生时,我已经转储了堆栈跟踪。看起来onAfterUpdate
由incrementViewCounter(..)
方法触发,由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});
答案 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);
}
}