Spring Boot引用完整性约束违反问题排查求助
Hey there, let's dig into that referential integrity constraint violation you're hitting when starting your tests. I've looked over your setup, and here's what's going wrong and how to fix it.
The Root Cause
The core issue is the order of your insert statements in data.sql. You're adding records to the ARTICLE table first, but those articles reference a user with ID=1 that doesn't exist yet—you insert the USER records after the articles. Relational databases enforce foreign key constraints strictly: the referenced parent record (in this case, the user) must exist before any child records (articles) that link to it can be created.
Your Entity Setup (for reference)
Article Entity
@Entity @Table(name = "ARTICLE") @Getter @Setter public class Article extends BaseEntity { private String title; private String name; private String iconName; @ManyToOne @JoinColumn(name = "AUTHOR_ID") private UserItem author; private Long editorId; @Lob private String article; }
UserItem Entity
@Entity @Table(name = "USER") @Getter @Setter @EqualsAndHashCode(callSuper = false, of = { "username", "company" }) public class UserItem extends BaseEntity { private String username; private String name; private String lastName; private String phone; private String password; private String company; private String reasonsForAccess; private Integer failLogins = 0; private boolean enabled = true; private boolean accountNonExpired; private boolean accountNonLocked; private boolean passwordNonExpired; private boolean credentialsNonExpired; @ManyToMany(fetch = FetchType.LAZY) @JoinTable( name = "USER_TO_ROLE", joinColumns = @JoinColumn(name = "USER_ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID")) private Set<RoleItem> roles; @ManyToMany(cascade = { CascadeType.PERSIST }, fetch = FetchType.LAZY) @JoinTable( name = "USER_ANSWER", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "QUESTION_ANSWER_ID") } ) Set<QuestionAnswerItem> answers = new HashSet<>(); @OneToMany(mappedBy = "author") private Set<Article> articles; }
The Fixes
Here's how to resolve the issue:
Reorder your
data.sqlinserts
Move theINSERT INTO PUBLIC.USERblock before theINSERT INTO PUBLIC.ARTICLEblock. This ensures the user with ID=1 exists when you insert articles that reference it. Your corrected script should look like this:-- Insert users first to satisfy foreign key constraints INSERT INTO PUBLIC.USER(ID, VERSION, CREDENTIALS_NON_EXPIRED, ACCOUNT_NON_EXPIRED, ACCOUNT_NON_LOCKED, COMPANY, ENABLED, FAIL_LOGINS, LAST_NAME, NAME, PASSWORD, PASSWORD_NON_EXPIRED, PHONE, REASONS_FOR_ACCESS, USERNAME) VALUES (1, 7, TRUE, TRUE, TRUE, 'lingaro', TRUE, 0, 'admin', 'admin', '$2a$11$TiefIbi6p15IAlGZsTIxquCNDrRCCjmzt9lTN0/D.toRFDVG3ECYO', TRUE, NULL, 'good', 'admin@mail.com'), (2, 0, TRUE, TRUE, TRUE, 'lingaro', TRUE, 0, 'user', 'user', '$2a$10$GS4IiuO9ygrHOr2e.lFx4euYACa6ZENz52KmGx8l.WCEqH03.HPsO', TRUE, NULL, 'good', 'user@mail.com'), (33, 4, TRUE, TRUE, TRUE, 'lingaroaaaaaaaa', TRUE, 0, 'admin', 'admin', '$2a$10$AJMuV2lAeg1XQoPIYQklju9t6aWyVrPMreXVOCaRgJhoxsp831Yhe', TRUE, NULL, 'good good', 'admin1'), (97, 0, TRUE, TRUE, TRUE, 'PG', TRUE, 0, 'hu_ta', 'hu_ta', '$2a$10$3opTpBQkdbvt8AA1aEOaM.YyCHh98ODxsPBlQ6IrX23o9HxUDyALq', TRUE, NULL, 'Ping Federation', 'hu_ta'), (161, 0, TRUE, TRUE, TRUE, 'PG', TRUE, 0, 'tatar.ht', 'tatar.ht', '$2a$10$iDfgmuKJI1YHRK4DKsm4mOZ/CdnE.5GoWYijEzdsdU/SnulJCHRYS', TRUE, NULL, 'Ping Federation', 'tatar.ht'); -- Now insert articles that reference existing users INSERT INTO PUBLIC.ARTICLE(ID, VERSION, ARTICLE, AUTHOR_ID, ICON_NAME, NAME, TITLE, EDITOR_ID) VALUES (4, 0, 'clobclobyolo', 1, 'book', 'Introduction to 1, Consumer Place', 'one', null), (5, 0, 'clobclobyolo', 1, 'mail', 'Email Solution (Digital Marketing Center)', 'one', null), (6, 0, 'clobclobyolo', 1, 'glob', 'Global Registration System (GRS)', 'one', null), (7, 0, 'clobclobyolo', 1, 'ticket', 'Ticketing Tool to drive CRM work (Service Now)', 'one', null), (8, 0, 'clobclobyolo', 1, 'pie-chart', '1.Consumer Place Reporting', 'one', null), (9, 0, 'clobclobyolo', 1, 'sms', 'SMS Solution', 'one', null), (10, 0, 'clobclobyolo', 1, 'list', 'Driving trial through Brand Propensity Model', 'one', null), (11, 0, 'clobclobyolo', 1, 'line-chart', 'Data Integration Capabilities', 'one', null), (12, 0, 'clobclobyolo', 1, 'application', 'What is DMP, CRM and DMP better together', 'one', null), (13, 0, 'clobclobyolo', 1, 'bar-chart', 'Data Source performance Tracking', 'one', null), (14, 0, 'clobclobyolo', 1, 'facebook', 'Facebook Leads Campaigns', 'one', null), (15, 0, 'clobclobyolo', 1, 'cloud-glob', 'Learn more about Data Enrichments', 'one', null);Optional: Split scripts for better maintainability
If your data setup grows more complex, split inserts into separate files (e.g.,user-data.sqlandarticle-data.sql). Then use Spring's@Sqlannotation in your test class to enforce execution order:@Sql(scripts = {"classpath:user-data.sql", "classpath:article-data.sql"}) @SpringBootTest public class YourTestClass { // Test methods go here }Verify foreign key constraints (if needed)
Double-check that theARTICLE.AUTHOR_IDcolumn has a foreign key constraint pointing toUSER.ID. Your JPA annotations should handle this when Hibernate generates the schema, but if you're using a pre-existing schema, confirm the constraint exists in your database.
The Error You Encountered (for reference)
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInst...
内容的提问来源于stack exchange,提问作者Jack_Russell




