Passed List Had More than One Value when Calling Dashboard

お困りですか?

アトラシアン コミュニティをご利用ください。

コミュニティに質問

症状

症状 1

Users trying to access the dashboard will encounter a System Error page containing an exception like:

java.lang.IllegalArgumentException: Passed List had more than one value.
at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:58)
at com.atlassian.jira.portal.OfBizPortalPageStore.getPortalPageByOwnerAndName(OfBizPortalPageStore.java:135)
at com.atlassian.jira.portal.CachingPortalPageStore.getPortalPageByOwnerAndName(CachingPortalPageStore.java:160)
at com.atlassian.jira.portal.DefaultPortalPageManager.getPortalPageByName(DefaultPortalPageManager.java:152)
at com.atlassian.jira.bc.portal.AbstractPortalPageService.validateForUpdate(AbstractPortalPageService.java:401)
at com.atlassian.jira.dashboard.permission.JiraPermissionService.isWritableBy(JiraPermissionService.java:63)
at com.atlassian.jira.dashboard.permission.JiraGadgetPermissionManager.filterGadgets(JiraGadgetPermissionManager.java:54)
...

or Application logs also contain the following ERROR report:

...
Exception caught in 500 page Passed List had more than one value.
java.lang.IllegalArgumentException: Passed List had more than one value.
	at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:58)
	at com.atlassian.jira.portal.OfBizPortalPageStore.getPortalPageByOwnerAndName(OfBizPortalPageStore.java:135)
	at com.atlassian.jira.portal.CachingPortalPageStore.getPortalPageByOwnerAndName(CachingPortalPageStore.java:160)
...

症状 2

Users are trying to access Jira or load the System dashboard, they are possibly presented with an HTTP 500 error and the following exception is present in the application log:

Servlet.service() for servlet [action] threw exception
java.lang.IllegalArgumentException: Passed List had more than one value.
        at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:68)
        at com.atlassian.jira.portal.OfBizPortalPageStore.getSystemDefaultPortalPage(OfBizPortalPageStore.java:197)
        at com.atlassian.jira.portal.CachingPortalPageStore.getSystemDefaultPortalPage(CachingPortalPageStore.java:86)
        at com.atlassian.jira.portal.DefaultPortalPageManager.getSystemDefaultPortalPage(DefaultPortalPageManager.java:154)
        at com.atlassian.jira.bc.portal.DefaultPortalPageService.getSystemDefaultPortalPage(DefaultPortalPageService.java:159)
        at com.atlassian.jira.web.action.Dashboard.getPageIdForUser(Dashboard.java:574)
        at com.atlassian.jira.web.action.Dashboard.initialiseCurrentDashboardId(Dashboard.java:536)
        at com.atlassian.jira.web.action.Dashboard.getCurrentDashboardId(Dashboard.java:246)
        at com.atlassian.jira.web.action.Dashboard.getCurrentDashboardState(Dashboard.java:259)
        at com.atlassian.jira.web.action.Dashboard.doValidation(Dashboard.java:154)
        ... 2 filtered

Diagnoses

Diagnosis 1

Further proof can be determined with the following query, which should return the username of the dashboard owner and the dashboard name for the affected dashboards:

SELECT username, pagename, count(pagename) FROM portalpage GROUP BY username,pagename HAVING count(pagename) > 1;

Diagnosis 2

There could be multiple unowned dashboards, i.e. where the username is set to null, run the following to see if you have this problem:

SELECT * FROM portalpage WHERE username IS NULL; 

If the above query returns more than one row, you're affected by this problem - please refer to Resolution 2 below.

原因

The portalpage table is used to store users' dashboards. Normally, it should contain one different pagename for each user. It should not contain names of duplicated pages per user, nor should it contain null for any dashboards other than the 'System dashboard'. If there are duplicates or dashboards not with a valid username, the "Passed List had more than one value" exception will occur.

Here is the code from OfBizPortalPageStore, where the application is expecting a single value from the underlying database:

final GenericValue pageGV = EntityUtil.getOnly(delegator.findByAnd(Table.NAME, EasyMap.build(Column.USERNAME, owner.getName(), Column.PAGENAME, name), DEFAULT_ORDER_BY_CLAUSE));

ソリューション

Resolution 1 - for Diagnosis 1

Remove the duplicate tuples from the portalpage table by using the username and pagename column. Use the diagnosis section above for reference. For example:

データベースの変更を行う場合は 必ず事前にバックアップを取得してください。可能な場合はテスト サーバーで変更を試すことをおすすめします。

METHOD 1 - for Resolution 1
  1. Running the below query will provide all the duplicated entries with their ids:

    select username,id from portalpage where username in (SELECT username FROM portalpage GROUP BY username,pagename HAVING count(pagename) > 1)
  2. Delete all the rows except one row for each of those users using the ID of the row.
METHOD 2 - for Resolution 1

Run the below SQL for a direct deletion of all the duplicated rows. This has been tested only on PostgreSQL:

DELETE
FROM portalpage p1 USING
  (SELECT username,
          id
   FROM portalpage
   WHERE username IN
       (SELECT username
        FROM portalpage
        GROUP BY username,
                 pagename HAVING count(pagename) > 1)) p2,
  (SELECT username,
          max(id) maxid
   FROM portalpage
   WHERE username IN
       (SELECT username
        FROM portalpage
        GROUP BY username,
                 pagename HAVING count(pagename) > 1)
   GROUP BY username) p3
WHERE p1.username = p2.username
  AND p3.maxid != p1.id
  AND p3.username = p2.username;

Resolution 2 - for Diagnosis 2

First, choose one of the dashboards returned by the query in Diagnosis 2 to be the default dashboard (usually this will be the built-in default dashboard with ID 10000), then choose a user account to be the new owner of the other dashboards.

Next, update the other dashboards using the SQL query below, replacing <new_owner_username> with the username of the chosen user account and <default_dashboard_id> with the ID of the default dashboard (you can obtain this from the results of the query in Diagnosis 2):

UPDATE portalpage SET username = '<new_owner_username>' WHERE id IN (SELECT id FROM portalpage WHERE username IS NULL AND id != <default_dashboard_id>);
最終更新日 2024 年 4 月 19 日

この内容はお役に立ちましたか?

はい
いいえ
この記事についてのフィードバックを送信する
Powered by Confluence and Scroll Viewport.