RE: DXP 7.1 User Deletion Using API Throwing Error

Gopal Prasad Satapathy, modified 5 Years ago. Junior Member Posts: 51 Join Date: 3/29/18 Recent Posts
Hello,
Using Liferay Digital Experience Platform 7.1.10 GA1 , dxp-11-7110.
Using a custom job for deletion of users and it uses com.liferay.portal.kernel.service.UserLocalService deleteUser() for deletion.
But for certain users getting below exception during deletion. Any pointer on what could be the cause?

2020-01-29 20:04:42 ERROR RemoveUserService:53 - Could not remove user
com.liferay.portal.kernel.exception.SystemException: java.lang.NullPointerException
at com.liferay.portal.kernel.service.persistence.impl.BasePersistenceImpl.processException(BasePersistenceImpl.java:269)
at com.liferay.counter.service.persistence.impl.CounterFinderImpl._obtainIncrement(CounterFinderImpl.java:390)

at com.liferay.counter.service.persistence.impl.CounterFinderImpl.createCounterRegister(CounterFinderImpl.java:234)
at com.liferay.counter.service.persistence.impl.CounterFinderImpl.createCounterRegister(CounterFinderImpl.java:197)
at com.liferay.counter.service.persistence.impl.CounterFinderImpl.getCounterRegister(CounterFinderImpl.java:257)
at com.liferay.counter.service.persistence.impl.CounterFinderImpl.reset(CounterFinderImpl.java:162)
at com.liferay.counter.service.impl.CounterLocalServiceImpl.reset(CounterLocalServiceImpl.java:74)
at sun.reflect.GeneratedMethodAccessor1959.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:153)
at com.liferay.portal.spring.transaction.CounterTransactionExecutor._execute(CounterTransactionExecutor.java:168)
at com.liferay.portal.spring.transaction.CounterTransactionExecutor.execute(CounterTransactionExecutor.java:87)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:113)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:125)
at com.sun.proxy.$Proxy30.reset(Unknown Source)
at com.liferay.portal.service.impl.LayoutLocalServiceImpl.deleteLayouts(LayoutLocalServiceImpl.java:687)
at sun.reflect.GeneratedMethodAccessor1940.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.service.impl.LayoutLocalServiceStagingAdvice$LayoutLocalServiceStagingInvocationHandler._invoke(LayoutLocalServiceStagingAdvice.java:751)
at com.liferay.portal.service.impl.LayoutLocalServiceStagingAdvice$LayoutLocalServiceStagingInvocationHandler.invoke(LayoutLocalServiceStagingAdvice.java:638)
at com.sun.proxy.$Proxy218.deleteLayouts(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1940.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:153)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor._execute(DefaultTransactionExecutor.java:203)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:94)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:113)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.service.ServiceContextAdvice.invoke(ServiceContextAdvice.java:51)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:125)
at com.sun.proxy.$Proxy92.deleteLayouts(Unknown Source)
at com.liferay.portal.service.impl.LayoutSetLocalServiceImpl.deleteLayoutSet(LayoutSetLocalServiceImpl.java:103)
at sun.reflect.GeneratedMethodAccessor1943.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.service.impl.LayoutSetLocalServiceStagingAdvice$LayoutSetLocalServiceStagingInvocationHandler.invoke(LayoutSetLocalServiceStagingAdvice.java:118)
at com.sun.proxy.$Proxy219.deleteLayoutSet(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1943.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:153)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor._execute(DefaultTransactionExecutor.java:203)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:94)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:113)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.service.ServiceContextAdvice.invoke(ServiceContextAdvice.java:51)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:125)
at com.sun.proxy.$Proxy105.deleteLayoutSet(Unknown Source)
at com.liferay.portal.service.impl.GroupLocalServiceImpl.deleteGroup(GroupLocalServiceImpl.java:924)
at sun.reflect.GeneratedMethodAccessor2023.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:153)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor._execute(DefaultTransactionExecutor.java:203)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:94)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:113)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:125)
at com.sun.proxy.$Proxy44.deleteGroup(Unknown Source)
at com.liferay.portal.service.impl.UserLocalServiceImpl.deleteUser(UserLocalServiceImpl.java:1896)
at sun.reflect.GeneratedMethodAccessor1953.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.kernel.bean.ClassLoaderBeanHandler.invoke(ClassLoaderBeanHandler.java:66)
at com.sun.proxy.$Proxy566.deleteUser(Unknown Source)
at com.liferay.portal.kernel.service.UserLocalServiceWrapper.deleteUser(UserLocalServiceWrapper.java:924)
at sun.reflect.GeneratedMethodAccessor1953.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.kernel.bean.ClassLoaderBeanHandler.invoke(ClassLoaderBeanHandler.java:66)
at com.sun.proxy.$Proxy567.deleteUser(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1953.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:153)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor._execute(DefaultTransactionExecutor.java:203)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:94)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:113)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:130)
at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:125)
at com.sun.proxy.$Proxy42.deleteUser(Unknown Source)
at be.bpost.home.portlets.usersync.service.liferay.RemoveUserService.removeUser(RemoveUserService.java:50)
at be.bpost.home.portlets.usersync.service.liferay.RemoveUserService.lambda$removeUsers$0(RemoveUserService.java:42)
at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1556)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647)
at be.bpost.home.portlets.usersync.service.liferay.RemoveUserService.removeUsers(RemoveUserService.java:39)
at be.bpost.home.portlets.usersync.job.BpostLiferayUserImportJob.importUsers(BpostLiferayUserImportJob.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:269)
at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:257)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.lang.NullPointerException
at com.liferay.counter.service.persistence.impl.CounterFinderImpl._obtainIncrement(CounterFinderImpl.java:371)
... 114 more

Thanks,
Gopal
Gopal Prasad Satapathy, modified 5 Years ago. Junior Member Posts: 51 Join Date: 3/29/18 Recent Posts
Can somebody please help me with this issue?
thumbnail
David H Nebinger, modified 5 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Did you open a support ticket?
Gopal Prasad Satapathy, modified 5 Years ago. Junior Member Posts: 51 Join Date: 3/29/18 Recent Posts
Hello David ,Yes. We did create a support ticket for this. But they are asking to go for liferay professional services for further help.
So wanted to check here if anybody has faced such issues or if someone can suggest what could be going wrong.
Thanks,Gopal
thumbnail
David H Nebinger, modified 5 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
If I were trying to bulk delete users, I don't think I'd go through UserLocalService to delete them directly.

Instead I'd use an ActionableDynamicQuery so they can be deleted within a single transaction.

How did you implement your bulk delete?
Gopal Prasad Satapathy, modified 5 Years ago. Junior Member Posts: 51 Join Date: 3/29/18 Recent Posts
Hello David,
Here is how we are performing the deletion.


@Service
public class RemoveUserService {
    @Autowired
    private UserLocalService userLocalService;
    @Autowired
    private ImportResultsManager resultsManager;
    public void removeUsers(Set<User> usersToRemove) {
        ImportResultModel results = resultsManager.getResults();
        ImportResultLineModel deleteLine = results.getImportResults().get("delete");
        deleteLine.setTasks(usersToRemove.size());
        deleteLine.start();
        int usersToRemoveCount = usersToRemove.size();
        if (usersToRemoveCount > 0) {
            AtomicInteger removeCounter = new AtomicInteger(1);
            usersToRemove.stream().forEach(user -> {
                removeUser(deleteLine, user);
            });
        }
        deleteLine.end();
    }
   

private void removeUser(ImportResultLineModel deleteLine, User user) {
        try {
            userLocalService.deleteUser(user);
            deleteLine.addSussess();
        } catch (PortalException | SystemException e) {
            LOGGER.error("Could not remove user", user, e);
            deleteLine.addError("Could not remove user: " + user.getEmailAddress() + " | " + e);
        }
    }
}

Thanks,
Gopal
thumbnail
David H Nebinger, modified 5 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Ugh, yeah, you're deleting one by one, quite painful.

how about something resembling:


public void deleteSomeUsers(final List<long> userIds) {
  ActionableDynamicQuery adq = _userLocalService.getActionableDynamicQuery();
  adq.setAddCriteriaMethod(new ActionableDynamicQuery.AddCriteriaMethod () {

    @Override
    public void addCriteria(DynamicQuery dq) {
      dq.add(RestrictionsFactoryUtil.in("userId", userIds));
    }
  });
  
  adq.setPerformActionMethod(new ActionableDynamicQuery.PerformActionMethod<user>() {

    @Override
    public void performAction(User user) {
      _userLocalService.deleteUser(user);
    }
  });
  
  try {
    adq.peformActions();
  } catch (Exception e) {
    _log.error("Error deleting users: " + e.getMessage(), e);
    throw new PortalException("Failed deleting users.", e)
  }
}
</user></long>
When you go this route, the delete is in bulk and within a transaction. I wouldn't try to sent 10k user ids to this method, I'd want a window of, I don't know, like 50 user ids at a pop. You'll want to try this out in test and see just how many you can do before your database starts throwing transaction size exceptions.