I have a spring-based Java EE web application. there is a repository layer (data access object layer) that i am testing using junit. i use maven to build and test my project.
my problem is this: when i run the tests on windows, the automated/default rollback behavior of spring works, however, when i deploy to my linux development server and attempt to run the tests, the rollback behavior does not seem to work.
here is a sample table. notice that the user name field is specified to be unique.
create table user (
id mediumint not null auto_increment,
username varchar(50),
passwd varchar(50),
unique(username)
);
here is my plain-old-java-object (pojo) modeling this table.
@Entity
@Table(name="user")
public class User {
@Column(name="id")
public int id;
@Column(name="username")
public String username;
@Column(name="passwd")
public String passwd;
public void User() { }
public void User(String username, String passwd) {
this.username = username;
this.passwd = passwd;
}
}
and then i have a JPA repository to persist a user as follows.
@Repository
public class JpaUserRepository {
@PersistenceContext
EntityManager em;
public User find(int id) {
User user = this.em.find(User.class, id);
return user;
}
public void save(User user) {
this.em.persist(user);
}
public void delete(User user) {
this.em.remove(user);
}
}
my unit tests using junit is as follows.
@ContextConfiguration(locations={"classpath:spring/business.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class JpaUserRepositoryTests {
@AutoWired
UserRepository userRepository;
@Test
@Transactional
public void testSave() {
User user = new User("user1","pw");
userRepository.save(userRepository);
user = userRepository.find(user.id);
Assert.assertNotNull(user);
}
@Test
@Transactional
public void testDelete() {
User user = new User("user1","pw");
userRepository.save(userRepository);
user = userRepository.find(user.id);
Assert.assertNotNull(user);
userRepository.delete(user);
user = userRepository.find(user.id);
Assert.assertNull(user);
}
}
again, on windows, when i run "mvn clean test", i get no failures. however, when i run this on my linux (CentOS 6.4 x64) box, i get a org.hibernate.exception.ConstraintViolationException because of the "user1" value.
i did some searching on stackoverflow. here's what i tried.
- used the @Rollback annotation to every method in the **Tests classes.
- used @TransactionConfiguration(defaultRollback=true) at the class level on all **Tests classes.
however, neither of these modifications work.
note the versions and/or differences of my windows vs linux environment. i'm not sure they make a difference.
- spring framework 3.2.2.RELEASE
- spring jpa 1.3.1.RELEASE
- maven surefire plugin 2.15
- maven 3.0.5 (version 3.1.0 on linux)
- junit 4.11
- JDK 1.7
- MySql 5.6.11 (version 5.1.69 on linux)
also, please note that after "mvn clean test", on windows, if i do a
select * from user;
then i get 0 results. but on linux, i do see that the user row/record is in the table. this is the reason why i think rollback is not working on linux.