com.liferay.portal.kernel.exception.NoSuchUserException: No User exists with the primary key NNNNNNNNのため、Import by Groupを使用して LDAP ユーザーをインポートできません。

問題

  • 以下のエラーにより Group import 方式で LDAP ユーザーをインポートできない場合、データベースの Users_UserGroups テーブルに、孤立したエントリが存在する可能性があります。: com.liferay.portal.kernel.exception.NoSuchUserException: No User exists with the primary key NNNNNNNN

環境

  • Liferay DXP 7.4

解決

  • Users_UserGroupsテーブルは、ユーザをそのユーザが所属するユーザー・グループにマッピングします。

    LDAP グループのインポートが失敗する場合は、データベースに存在しないユーザーを指す孤立したデータがこのテーブルに存在する可能性が高くなります。グループ インポート ログの例を次に示します:
    com.liferay.portal.kernel.exception.NoSuchUserException: No User exists with the primary key NNNNNNNN

    これは、 Users_UserGroups テーブルに、 NNNNNNという userId を持つエントリ(またはエントリ)が存在することを意味しますが、 User_ テーブルに対応するエントリは存在しません。 これが、例外につながります。 インポート処理中、LiferayはインポートされたLDAPグループのメンバーであるすべてのユーザーを検索しようとします。 このため、 Users_UserGroups テーブルに問い合わせが行われ、最終的にこのExceptionが発生します。

    この情報は、 Users_UserGroups テーブルに、以下のようなクエリを実行して、孤立したデータが存在しないかどうかを確認することで確認できます:
    SELECT * FROM Users_UserGroups WHERE userId NOT IN (SELECT userId FROM User_)

  • 重複するエントリーが見つかった場合、手動でそのエントリーをデータベースから削除しないことを強くお勧めします。 代わりに、コントロールパネル > サーバー管理 > スクリプト から、次のGroovyスクリプトを実行できます。

    注意:このスクリプトを実行する前に、Liferay環境、関連データベース、ドキュメントリポジトリのバックアップを作成するために、サーバーをシャットダウンすることを確認してください。 これは、何らかの問題が発生した場合に、復元ポイントを確保するためです。 完了後、サーバーを再起動し、Scriptコンソールに入り、以下のスクリプトを実行してください。
import com.liferay.portal.kernel.dao.jdbc.AutoBatchPreparedStatementUtil;
import com.liferay.portal.kernel.dao.jdbc.DataAccess;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DeleteOrphanedUsersUserGroupsData {

	public void doDeleteOrphanedUsersUserGroupsData() {
		Connection con = null;
		PreparedStatement ps1 = null;
		PreparedStatement ps2 = null;
		ResultSet rs = null;

		try {
			con = DataAccess.getConnection();

			ps1 = con.prepareStatement(
				"select distinct(userId) from Users_UserGroups where userId " +
					"not in (select userId from User_)");
			ps2 = AutoBatchPreparedStatementUtil.concurrentAutoBatch(
				con, "delete from Users_UserGroups where userId = ?");

			rs = ps1.executeQuery();

			while (rs.next()) {
				long userId = rs.getLong("userId");

				if (_log.isInfoEnabled()) {
					_log.info(
						"Found orphaned user id " + userId + " in " +
							"Users_UserGroups table. Queuing entries with " +
								"this user id for deletion.");
				}

				ps2.setLong(1, userId);

				ps2.addBatch();
			}

			ps2.executeBatch();

			if (_log.isInfoEnabled()) {
				_log.info("Successfully executed all queued deletions");
			}
		}
		catch (Exception e) {
			_log.error("Error while executing script", e);
		}
		finally {
			DataAccess.cleanUp(ps1);
			DataAccess.cleanUp(con, ps2, rs);
		}
	}

	private static Log _log = LogFactoryUtil.getLog(
		DeleteOrphanedUsersUserGroupsData.class);

}

out.println(
	"Running groovy script to delete orphaned data from the Users_UserGroups " +
		"table...");

DeleteOrphanedUsersUserGroupsData deleteOrphanedUsersUserGroupsData =
	new DeleteOrphanedUsersUserGroupsData();

deleteOrphanedUsersUserGroupsData.doDeleteOrphanedUsersUserGroupsData();

out.println("Script finished running.");

この作業が完了したら、再度グループインポートを実行し、この動作が解決されることを確認してください。

追加情報

この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています