CPLEX has no way of telling whether a UserCut would cut off integer solutions or not.
So it will usually add any violated cut that you specify in the UserCutCallback. You can get a little more control over what CPLEX does with your cuts by using different values from the use_cut enumeration as use arguments to the callback's add() function. The default for this argument is force (0) which forces CPLEX to use the cut.
In general, in a UserCutCallback you are supposed not to add any cuts that may cut off integer solutions. There is one exception to this rule (and this seems to be what you are doing): if you simultaneously use a LazyConstraintCallback that separates the same cuts then it is fine to also add user cuts that may cut off integral solutions.
#CPLEXOptimizers#DecisionOptimization