Summary: When a custom attribute is assigned to a group and provisioned to the gr_to_mp.gr_mp_group_attributes table and then the attribute is deleted, a subsequent group delete will throw a RuntimeException. This occurs in both 4.17.7 and 4.18.1. I haven't tested any other Grouper versions. It might have happened even earlier but I had not tested this exact scenario before.Setup: * Have a custom attribute (ours is oracle-role).
- Assign the attribute, with a value, to a group.
- Run the full provisioner.
- Check the gr_to_mp.gr_mp_group_attributes table - entries look correct.
------------{}----------{}+{}----------------------{}{}---{}{} |group_id_index|attribute_name|attribute_value |deleted| {}----------------------{}---------------------------+ |1000049 |oracle-role |STUDENT_ANALYTICS_CONSUMER|F | |1000049 |role-name |testgroup1 |F | {}----------------------{}-----------------------------+ *
Remove the attribute from the group.
- Run the full provisioner.
- Check the gr_to_mp.gr_mp_group_attributes table. Note the change of value to <null> and deleted NOT set to 'T'.
------------{}----------{}+{}-----------{}{}---{}{} |group_id_index|attribute_name|attribute_value|deleted| {}----------------------{}----------------+ |1000049 |oracle-role |null |F | |1000049 |role-name |testgroup1 |F | {}----------------------{}------------------+
- Delete the group.
- Run the full provisioner.
- ERROR status with RuntimeException
- All gr_to_mp tables are correct EXCEPT the gr_to_mp.gr_mp_group_attributes table, which has not changed.
------------{}----------{}+{}-----------{}{}---{} |group_id_index|attribute_name|attribute_value|deleted| +{}----------{}{}----------{}{}-----------{}{}---{} |1000049 |oracle-role |null |F | |1000049 |role-name |testgroup1 |F | +{}----------{}{}----------{}{}-----------{}{}-----
2025-05-30 10:55:37.088: ERROR: Error in provisioner 'midpoint' - 'wlk11n7c' with group: Group(matchingAttrs: ArrayList(1): [0]: [id_index, val: 1000049, compareVal: 1000049, currentValue: true], exception: java.lang.RuntimeException: Number in update batch doesnt match where clause batch size, provisioned: false, attr[deleted]: "F", attr[description]: "testgroup1 in app2", attr[displayName]: <null>, attr[display_name]: "DepartmentalGroups:domain1:app:app2:testgroup1", attr[group_name]: "dpt:domain1:app:app2:testgroup1", attr[id]: <null>, attr[idIndex]: <null>, attr[id_index]: 1000049, attr[last_modified]: 1748610569752, attr[name]: <null>, attr[oracle-role]: <null>, attr[role-name]: "testgroup1", attr[target]: <null>, (role-name: del: 1), (deleted: del: 1), (group_name: del: 1), (description: del: 1), (id_index: del: 1), (display_name: del: 1), (last_modified: del: 1), (oracle-role: del: 1), del group_name "dpt:domain1:app:app2:testgroup1", del role-name "testgroup1", del oracle-role <null>, del id_index 1000049, del display_name "DepartmentalGroups:domain1:app:app2:testgroup1", del description "testgroup1 in app2", del last_modified 1748610569752, del deleted "F", del id <null>, del displayName <null>, del name <null>, del idIndex <null>, del target <null>, del group_name "dpt:domain1:app:app2:testgroup1", del role-name "testgroup1", del oracle-role <null>, del id_index 1000049, del display_name "DepartmentalGroups:domain1:app:app2:testgroup1", del description "testgroup1 in app2", del last_modified 1748610569752, del deleted "F", del id <null>, del displayName <null>, del name <null>, del idIndex <null>, del target <null>)java.lang.RuntimeException: Number in update batch doesnt match where clause batch size at edu.internet2.middleware.grouper.util.GrouperUtil.assertion(GrouperUtil.java:4355) at edu.internet2.middleware.grouper.app.sqlProvisioning.SqlProvisionerCommands.updateObjectsOldValueNotNull(SqlProvisionerCommands.java:583) at edu.internet2.middleware.grouper.app.sqlProvisioning.SqlProvisionerCommands.updateObjects(SqlProvisionerCommands.java:521) at edu.internet2.middleware.grouper.app.sqlProvisioning.SqlProvisioningDao.deleteGroups(SqlProvisioningDao.java:973) at edu.internet2.middleware.grouper.app.provisioning.targetDao.GrouperProvisionerTargetDaoAdapter.deleteGroupsHelper(GrouperProvisionerTargetDaoAdapter.java:3960) at edu.internet2.middleware.grouper.app.provisioning.targetDao.GrouperProvisionerTargetDaoAdapter$29.callLogic(GrouperProvisionerTargetDaoAdapter.java:3905) at edu.internet2.middleware.grouper.app.provisioning.targetDao.GrouperProvisionerTargetDaoAdapter$29.callLogic(GrouperProvisionerTargetDaoAdapter.java:3900) at edu.internet2.middleware.grouper.util.GrouperUtil.executorServiceSubmit(GrouperUtil.java:14689) at edu.internet2.middleware.grouper.app.provisioning.targetDao.GrouperProvisionerTargetDaoAdapter.deleteGroups(GrouperProvisionerTargetDaoAdapter.java:3932) at edu.internet2.middleware.grouper.app.provisioning.targetDao.GrouperProvisionerTargetDaoAdapter.sendGroupChangesToTarget(GrouperProvisionerTargetDaoAdapter.java:477) at edu.internet2.middleware.grouper.app.provisioning.targetDao.GrouperProvisionerTargetDaoAdapter.sendChangesToTarget(GrouperProvisionerTargetDaoAdapter.java:393) at edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningLogic.provisionFull(GrouperProvisioningLogic.java:319) at edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningType$1.provision(GrouperProvisioningType.java:41) at edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningLogic.provision(GrouperProvisioningLogic.java:78) at edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioner.provision(GrouperProvisioner.java:881) at edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningFullSyncJob.runFullSync(GrouperProvisioningFullSyncJob.java:56) at edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningFullSyncJob$1.callback(GrouperProvisioningFullSyncJob.java:30) at edu.internet2.middleware.grouper.GrouperSession.callbackGrouperSession(GrouperSession.java:1063) at edu.internet2.middleware.grouper.GrouperSession.internal_callbackRootGrouperSession(GrouperSession.java:1132) at edu.internet2.middleware.grouper.GrouperSession.internal_callbackRootGrouperSession(GrouperSession.java:1099) at edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningFullSyncJob.run(GrouperProvisioningFullSyncJob.java:19) at edu.internet2.middleware.grouper.app.loader.OtherJobBase$2.callback(OtherJobBase.java:441) at edu.internet2.middleware.grouper.GrouperSession.callbackGrouperSession(GrouperSession.java:1063) at edu.internet2.middleware.grouper.GrouperSession.internal_callbackRootGrouperSession(GrouperSession.java:1132) at edu.internet2.middleware.grouper.GrouperSession.internal_callbackRootGrouperSession(GrouperSession.java:1099) at edu.internet2.middleware.grouper.app.loader.OtherJobBase.execute(OtherJobBase.java:394) at edu.internet2.middleware.grouper.app.loader.OtherJobBase.execute(OtherJobBase.java:378) at edu.internet2.middleware.grouper.app.loader.GrouperDaemonJob.execute(GrouperDaemonJob.java:57) at org.quartz.core.JobRunShell.run(JobRunShell.java:202) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) |