I am assuming Visit has a planning variable/shadow variable employee.
Is PayPeriod in a @ProblemFactCollection on the @PlanningSolution? If so, then I would write this constraint as:
```
constraintFactory
.forEach(Employee.class)
.join(PayPeriod.class)
.ifNotExists(Visit.class,
Joiners.equal((employee, payPeriod) -> employee, Visit::getEmployee),
Joiners.equal((employee, payPeriod) -> payPeriod, Visit::getPayPeriod))
.penalize("Employee has no visit for pay period", HardSoftScore.ONE_HARD);
```
If PayPeriod is not in a @ProblemFactCollection on the @PlanningSolution, it is trickier, since you would need to get the PayPeriod from the Visit, which leads to this constraint:
```
constraintFactory
.forEach(Visit.class)
.groupBy(Visit::getPayPeriod)
.join(Employee.class)
.ifNotExists(Visit.class,
Joiners.equal((payPeriod, employee) -> employee, Visit::getEmployee),
Joiners.equal((payPeriod, employee) -> payPeriod, Visit::getPayPeriod))
.penalize("Employee has no visit for pay period", HardSoftScore.ONE_HARD);
```