userVolunteerWork 엔티티
@Getter
@Entity
@Table(name = "USER_VOLUNTEERWORK", uniqueConstraints = @UniqueConstraint(columnNames = {"VOLUNTEER_WORK_ID", "USER_ID"}), indexes = @Index(name = "idx_status", columnList = "status"))
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class UserVolunteerWork extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "USER_ID")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "VOLUNTEER_WORK_ID")
private VolunteerWork volunteerWork;
@Column(name = "STATUS")
@Enumerated(EnumType.STRING)
private ApplyStatus status;
// 낙관적 락을 위해 사용했으나 효과 X
// @Version
// private Long version
public UserVolunteerWork(User user, VolunteerWork volunteerWork) {
this.user = user;
this.volunteerWork = volunteerWork;
this.status = ApplyStatus.PENDING;
}
public void updateStatus(ApplyStatus status) {
this.status = status;
}
@Override
public String toString() {
return "UserVolunteerWork{" +
"id=" + id +
", user=" + user +
", volunteerWork=" + volunteerWork +
", status=" + status +
'}';
}
}
해당 엔티티는 유저와 봉사활동 다대다 연관관계를 위한 중간 테이블이다.
@Transactional(timeout = 5)
public synchronized void approve(String email, Long volunteerWorkId, Long userId) throws IllegalAccessException {
// 문제 발생 첫번째 코드
UserVolunteerWork userVolunteerWork = userVolunteerRepository
.findByVolunteerWorkIdAndUserId(volunteerWorkId, userId)
.orElseThrow(EntityNotFoundException::new);
if (userVolunteerWork.getStatus() != ApplyStatus.PENDING) {
throw new IllegalStateException("대기 상태가 아닙니다. userVolunteerWorkId =" + userVolunteerWork.getId());
}
VolunteerWork volunteerWork = userVolunteerWork.getVolunteerWork();
Organization organization = userRepository.findByEmail(email).orElseThrow(EntityNotFoundException::new).getOrganization();
// 승인권한은 해당 기관담당만 가능하도록 해야함.
if (!volunteerWork.getOrganization().equals(organization)) {
throw new AuthorizationFailedException(AUTHORIZATION_ERR_MSG);
}
if (volunteerWork.getAppliedParticipants().get() >= volunteerWork.getMaxParticipants()) {
throw new IllegalAccessException();
}
User user = userVolunteerWork.getUser();
user.attendVolunteerWork(userVolunteerWork);
volunteerWork.attendUser(userVolunteerWork);
volunteerWork.increaseParticipants();
userVolunteerWork.updateStatus(ApplyStatus.APPROVED);
}
UserVolunteerRepositoryCustomImpl