I'm using Hibernate and Spring Data to model a very simple domain:
@Entity
public class User implements Serializable {
private static final long serialVersionUID = -5501812656863255674L;
@Id
private String emailAddress;
@Column
private String forename;
@Column
private String surname;
@Column
@Enumerated(EnumType.STRING)
private UserRole role;
@OneToMany(cascade = { CascadeType.ALL })
private List<Team> teams;
}
and
@Entity
public class Team implements Serializable {
private static final long serialVersionUID = -3734641391628154428L;
private static final BigDecimal STARTING_BUDGET = new BigDecimal(100);
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(unique = true)
private String name;
}
I then have an 'updateUser' method in a data service which does as it is named. The idea is that to add a Team to a User, this method would be used and the cascading would result in the Team being persisted in the database.
@Override
public void updateUser(final User user) throws IntegrationException {
if (userRepository.exists(user.getEmailAddress())) {
userRepository.save(user);
} else {
throw new IntegrationException(IntegrationExceptionCode.USER_NOT_FOUND);
}
}
I'm then unit testing this method using a HSQLDB database and Spring DBUnit to setup the initial database contents and the expected DB contents:
Initial DB Content Config
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<User emailAddress="user1@test.com" forename="User" surname="One" role="MANAGER" />
<Player />
<User_Team />
<Team />
</dataset>
Expected DB Content Config
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<User emailAddress="user1@test.com" forename="User" surname="One" role="MANAGER" />
<Player />
<Team id="1" name="Test Team" totalScore="0" status="INCOMPLETE" remainingBudget="100" />
<User_Team User_emailAddress="user1@test.com" Teams_id="1" />
</dataset>
I then have two tests: one which tests the update success; one which tests that a user which is not already in the system can't be updated.
Success Test
@Test
@ExpectedDatabase("UserData-WithTeam.xml")
public void testUpdateUser_AddedTeam_Success() throws Exception {
// arrange
final User user = UserTestDataBuilder.aManager(VALID_EMAIL_ADDRESS, "User", "One").withTeam().build();
// act
userDataService.updateUser(user);
// assert - done by @ExpectedDatabase annotation
}
'User Does Not Exist' Test
@Test
public void testUpdateUser_AddedTeam_UserDoesNotExist() throws Exception {
// arrange
thrownException.expect(IntegrationException.class);
thrownException.expect(CustomIntegrationExceptionMatcher.hasCode(IntegrationExceptionCode.USER_NOT_FOUND));
final User user = UserTestDataBuilder.aManagerWithEmailAddress(INVALID_EMAIL_ADDRESS).withTeam().build();
// act
userDataService.updateUser(user);
// assert
Assert.fail("Exception expected");
}
The 'success' test works fine. However, the 'failure case' test errors with the following error:
java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no action; FK_RVG5KHM9RO439HI17HPAUV5KG table: USER_TEAM
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.execute(Unknown Source)
at org.dbunit.database.statement.SimpleStatement.executeBatch(SimpleStatement.java:69)
at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:126)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
at com.github.springtestdbunit.DbUnitRunner.setupOrTeardown(DbUnitRunner.java:194)
at com.github.springtestdbunit.DbUnitRunner.beforeTestMethod(DbUnitRunner.java:66)
at com.github.springtestdbunit.DbUnitTestExecutionListener.beforeTestMethod(DbUnitTestExecutionListener.java:186)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:249)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no action; FK_RVG5KHM9RO439HI17HPAUV5KG table: USER_TEAM
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.StatementDML.performReferentialActions(Unknown Source)
at org.hsqldb.StatementDML.delete(Unknown Source)
at org.hsqldb.StatementDML.executeDeleteStatement(Unknown Source)
at org.hsqldb.StatementDML.getResult(Unknown Source)
at org.hsqldb.StatementDMQL.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.executeDirectStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 32 more
It seems to be suggesting that it can't tear down the test data added in the 'success' test (and I've added the @Ignore annotation to the success test and the failure test passes). My question is why? My cascade on the @OneToMany relationship is set to ALL so all entities saved as part of the User-Team relationship should be removed.
Does anyone have any ideas?
我认为您在USER_TEAM
表中有一个Integrity约束: UPDATE NO ACTION
这就是为什么给java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no action;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.