Я пытаюсь удалить старые токены для проверки электронной почты, прежде чем создавать новые в моем приложении Spring Boot. Запрос DELETE SQL отлично работает при выполнении непосредственно в базе данных, но при вызове метода репозитория JPA Data Spring старые токены не удаляются и остаются в базе данных. /> Классы объектов
User Entity: < /p>
@Entity
@Table(name = "user_details")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "email_id", unique = true, nullable = false)
private String emailId;
@Column(name = "email_verified", nullable = false)
private boolean emailVerified = false;
// other fields, constructors, getters/setters...
}
< /code>
emailverificationtoken Entity: < /p>
@Entity
@Table(name = "email_verification_token")
public class EmailVerificationToken {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "token", nullable = false, unique = true)
private String token;
@Column(name = "expiryDate", nullable = false)
private Instant expiryDate;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)
private User user;
// constructors, getters/setters...
}
< /code>
Интерфейс репозитория < /p>
@Repository
public interface EmailVerificationTokenRepository extends JpaRepository {
Optional findByToken(String token);
List findByUser(User user);
@Modifying
@Transactional
@Query(value = "DELETE FROM email_verification_token WHERE user_id = :userId", nativeQuery = true)
void deleteByUserId(@Param("userId") Long userId);
}
< /code>
Метод службы < /p>
@Service
public class UserService {
@Transactional
public void resendVerificationEmail(String emailId) {
User user = userRepository.findByEmailId(emailId)
.orElseThrow(() -> new IllegalArgumentException("User not found"));
if (user.isEmailVerified()) {
throw new IllegalArgumentException("Email is already verified");
}
// Check existing tokens
List existingTokens = emailVerificationTokenRepository.findByUser(user);
logger.info("Found {} existing tokens for user {}", existingTokens.size(), emailId);
if (!existingTokens.isEmpty()) {
// This delete operation doesn't work
emailVerificationTokenRepository.deleteByUserId(user.getId());
logger.info("Attempted to delete tokens for user ID: {}", user.getId());
// Tokens still exist after this call
List remainingTokens = emailVerificationTokenRepository.findByUser(user);
logger.info("After deletion, {} tokens remain", remainingTokens.size()); // Still shows old count
}
// Create new token
String token = UUID.randomUUID().toString();
Instant expiry = Instant.now().plusSeconds(1800);
EmailVerificationToken verificationToken = new EmailVerificationToken(token, expiry, user);
emailVerificationTokenRepository.save(verificationToken);
// Send email...
}
}
< /code>
Что работает, а не
DELETE FROM email_verification_token WHERE user_id = 5;
-- This successfully deletes the tokens
< /code>
Метод deletebyuserid () выполняется без ошибок
журналы показывают «Попытки удалить токенс для идентификатора пользователя: x»
Но токены остаются в Database
what quepend what let token Попробого
добавлено @transactional и @modizing annotations в метод репозитория
Используемый нативный запрос SQL вместо JPQL
ручной делеции с помощью EmailverVerificationTokenRepository.Delete (токен) в петле
udfulperificationtokenrepository.delete (token) в петле
fusher () после удаления операции
veried Qucl Quer /> Вопрос
Почему @Modifyfite Delete запрос фактически не удаляет записи из базы данных, когда один и тот же SQL -запрос работает нормально при выполнении напрямую? Метод выполняется без каких -либо исключений, но данные сохраняются в базе данных. < /P>
Схема базы данных: < /p>
CREATE TABLE email_verification_token (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
token VARCHAR(255) NOT NULL UNIQUE,
expiryDate TIMESTAMP NOT NULL,
user_id BIGINT NOT NULL,
FOREIGN KEY (user_id) REFERENCES user_details(id)
);
< /code>
Полный поток проблемы < /p>
Frontend/API Behavior:
POST /auth/register (with existing unverified email)
Response: 400 Bad Request
Console: "This email is registered but not verified."
< /code>
Вывод бэкэнд -консоли: < /p>
Found 1 existing tokens for user test@example.com
Attempted to delete tokens for user ID: 5
After deletion, 1 tokens remain // ← Should be 0
Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/cbor]
DEBUG HttpEntityMethodProcessor : Writing [{message=This email is registered but not verified., status=EMAIL_NOT_VERIFIED}]
DEBUG DispatcherServlet : Completed 400 BAD_REQUEST
< /code>
Цепочка проблем: < /p>
1-User пытается зарегистрироваться в существующей неверной электронной почте
2-backend попытки удалить старые токены проверки
3-delet Он обнаруживает электронное письмо как «непроверенный»
6-Frontend получает 400 вместо ожидаемого ответа на успех /повторной или повторной рецензии < /p>
Метод обслуживания выполняется без исключения исключений, но старые токены сохраняются в базе данных, что приводит к возвращению 400 плохой запросы вместо того, чтобы успешно повторно нанести по электронной почте. Проблема транзакции/настойчивости была бы очень оценена.
Подробнее здесь: https://stackoverflow.com/questions/796 ... n-in-datab
Мобильная версия