Summary
Após a correção do relacionamento User → GoogleDriveConnection, surgiu uma nova quebra de integridade referencial em testes E2E.
Os testes unitários e grande parte dos testes de integração continuam saudáveis:
O problema agora está isolado no fluxo de limpeza do banco durante os testes E2E.
❌ Sintoma observado
Erro recorrente:
org.springframework.dao.DataIntegrityViolationException
Referential integrity constraint violation:
public.interview_events FOREIGN KEY(application_id)
REFERENCES public.job_applications(id)
Falha ocorre durante:
ApplicationE2ETest.setUp()
AuthE2ETest.cleanDb()
Chamadas:
jobApplicationRepository.deleteAll()
Stack:
AuthE2ETest.cleanDb(AuthE2ETest.java:34)
ApplicationE2ETest.setUp(ApplicationE2ETest.java:33)
🎯 Root Cause
Foi introduzida uma dependência:
job_applications
↑
interview_events.application_id
Representação do domínio:
InterviewEvent
-> JobApplication
Durante o cleanup:
jobApplicationRepository.deleteAll();
a tabela pai está sendo removida antes dos registros filhos.
Estado do banco:
interview_events
└── application_id -> job_applications.id
Resultado:
O H2 impede a exclusão por ainda existirem referências ativas.
(Traduzindo do dialeto do banco: "você não pode apagar a casa enquanto ainda tem gente morando nela" 😅)
Impact
Isso provoca falhas em cascata em múltiplas suítes:
AuthE2ETest
Todos os testes quebram antes mesmo da execução real:
- register_shouldSetHttpOnlySecureSameSiteCookie
- logout_shouldReturnSuccess_andClearCookie
- login_shouldReturn401_whenWrongPassword
- me_shouldReturn403_whenAccessTokenInvalidOrExpired
e demais cenários.
ApplicationE2ETest
Além dos erros de setup:
getAll_withFilter_shouldReturnFilteredResults
há também efeito colateral:
Expected status code <200> but was <500>
Muito provavelmente erro secundário causado pelo estado inconsistente do banco após falha de limpeza.
✅ Suggested Fix (curto prazo)
Remover entidades filhas antes das entidades pai.
Antes:
@BeforeEach
void cleanDb() {
jobApplicationRepository.deleteAll();
usersRepository.deleteAll();
}
Depois:
@BeforeEach
void cleanDb() {
interviewEventRepository.deleteAll();
jobApplicationRepository.deleteAll();
usersRepository.deleteAll();
}
Se existir:
refreshTokenRepository.deleteAll();
googleDriveConnectionRepository.deleteAll();
seguir sempre:
Melhor abordagem estrutural
Adicionar cascata no relacionamento:
@OneToMany(
mappedBy="application",
cascade=CascadeType.ALL,
orphanRemoval=true
)
private List<InterviewEvent> events;
ou:
@OnDelete(action = OnDeleteAction.CASCADE)
Assim:
jobApplicationRepository.deleteAll()
automaticamente removeria:
⚠️ Observação arquitetural
O padrão está se repetindo:
Anterior:
User
-> GoogleDriveConnection
Agora:
JobApplication
-> InterviewEvent
Isso sugere um problema maior: a estratégia de cleanup está acoplada ao conhecimento manual de cada entidade filha.
Quanto mais o domínio crescer:
User
├── RefreshToken
├── GoogleDriveConnection
└── ...
JobApplication
├── InterviewEvent
├── Notes
└── ...
mais frágil o deleteAll() ficará.
Recommendation
Curto prazo:
✅ deletar InterviewEvent antes de JobApplication
Médio prazo:
✅ revisar cascade/orphanRemoval
Longo prazo:
✅ criar um TestDatabaseCleaner centralizado
Exemplo:
@Component
class TestDatabaseCleaner {
void clean() {
interviewEventRepository.deleteAll();
refreshTokenRepository.deleteAll();
googleDriveConnectionRepository.deleteAll();
jobApplicationRepository.deleteAll();
usersRepository.deleteAll();
}
}
Evita sair caçando FK quebrada a cada nova entidade adicionada (o famoso "apaguei uma hidra, nasceram três cabeças" 🐉).
Resultado esperado:
Tests run: XX
Failures: 0
Errors: 0
Green build ✅
Summary
Após a correção do relacionamento
User → GoogleDriveConnection, surgiu uma nova quebra de integridade referencial em testes E2E.Os testes unitários e grande parte dos testes de integração continuam saudáveis:
O problema agora está isolado no fluxo de limpeza do banco durante os testes E2E.
❌ Sintoma observado
Erro recorrente:
Falha ocorre durante:
Chamadas:
Stack:
🎯 Root Cause
Foi introduzida uma dependência:
Representação do domínio:
Durante o cleanup:
a tabela pai está sendo removida antes dos registros filhos.
Estado do banco:
Resultado:
O H2 impede a exclusão por ainda existirem referências ativas.
(Traduzindo do dialeto do banco: "você não pode apagar a casa enquanto ainda tem gente morando nela" 😅)
Impact
Isso provoca falhas em cascata em múltiplas suítes:
AuthE2ETest
Todos os testes quebram antes mesmo da execução real:
e demais cenários.
ApplicationE2ETest
Além dos erros de setup:
há também efeito colateral:
Muito provavelmente erro secundário causado pelo estado inconsistente do banco após falha de limpeza.
✅ Suggested Fix (curto prazo)
Remover entidades filhas antes das entidades pai.
Antes:
Depois:
Se existir:
seguir sempre:
Melhor abordagem estrutural
Adicionar cascata no relacionamento:
ou:
Assim:
automaticamente removeria:
O padrão está se repetindo:
Anterior:
Agora:
Isso sugere um problema maior: a estratégia de cleanup está acoplada ao conhecimento manual de cada entidade filha.
Quanto mais o domínio crescer:
mais frágil o
deleteAll()ficará.Recommendation
Curto prazo:
✅ deletar
InterviewEventantes deJobApplicationMédio prazo:
✅ revisar
cascade/orphanRemovalLongo prazo:
✅ criar um
TestDatabaseCleanercentralizadoExemplo:
Evita sair caçando FK quebrada a cada nova entidade adicionada (o famoso "apaguei uma hidra, nasceram três cabeças" 🐉).
Resultado esperado: