-
Integration Tests fail
Hi,
I am new to Spring Roo. I have created a project using this tool. My project has two domain objects: Person and Address. Person has a reference to Address. When I use Mysql and Hibernate, all my integration tests fail :(. But if I change database from mysql to hypersonic-in-memory all integration tests are ok (i mean pass). Can anyone please explains me this is happenning ? :confused:
Here is my integration test for Person:
package com.foo.neoroo.domain;
import java.util.Date;
import javax.sql.DataSource;
import junit.framework.Assert;
import org.springframework.beans.factory.annotation.Autow ired;
import org.springframework.jdbc.core.simple.SimpleJdbcTem plate;
import org.springframework.roo.addon.test.RooIntegrationT est;
import com.foo.neoroo.domain.Person;
import org.junit.Test;
@RooIntegrationTest(entity = Person.class)
public class PersonIntegrationTest {
private SimpleJdbcTemplate jdbcTemplate;
@Autowired
public void initializePersonIntegrationTest(DataSource ds){
jdbcTemplate = new SimpleJdbcTemplate(ds);
}
@Test
public void testMarkerMethod() {
int count = jdbcTemplate.queryForInt("select count(0) from Person");
Person person = new Person();
person.setFirstName("Sanjoy");
person.setLastName("Roy");
person.setDateCreated(new Date());
person.setDateUpdated(new Date());
person.persist();
count = jdbcTemplate.queryForInt("select count(0) from Person");
Assert.assertEquals(1, count);
System.out.println(person);
}
}
Integration Test for Address
package com.foo.neoroo.domain;
import javax.sql.DataSource;
import junit.framework.Assert;
import org.springframework.beans.factory.annotation.Autow ired;
import org.springframework.jdbc.core.simple.SimpleJdbcTem plate;
import org.springframework.roo.addon.test.RooIntegrationT est;
import com.foo.neoroo.domain.Address;
import org.junit.Test;
@RooIntegrationTest(entity = Address.class)
public class AddressIntegrationTest {
private SimpleJdbcTemplate jdbcTemplate;
@Autowired
public void initializeAddressIntegrationTest(DataSource ds){
jdbcTemplate = new SimpleJdbcTemplate(ds);
}
@Test
public void testMarkerMethod() {
int count = jdbcTemplate.queryForInt("select count(0) from Address");
Address address = new Address();
address.setHouseNo("70");
address.setPostcode("sd2 3ds");
address.persist();
System.out.println(address);
int count1 = jdbcTemplate.queryForInt("select count(0) from Address");
System.out.println(address);
Assert.assertEquals(1, count1);
}
}
Thanks in advance.
Cheers
Sanjoy
-
Have you created the database as InnoDB in MySQL? Hibernate won't do that as set up by Roo even if the user referred to in database.properties have the proper permissons to create databases. Possibly you'll need to give the user the proper permissions in the database you set up too, but if the user is an admin it might work anyway .
-
Thank you for your reply. I have created the database manually. I have checked all the tables. They all have innodb storage engine. I have granted all permissions to the database user that I have used in database.properties file. But still same problem. :(
-
Can you supply us with the stack traces? If you're new to Maven, they'd be in target/surefire-reports. It could still be a configuration problem. I know that I had to actually configure my MySQL to use InnoDB by default, or the tests failed.
Can you write a small piece of MySQL database script to begin a tran, do two updates, then try to issue a rollback, just to make 100% sure that the transaction engine is working properly?
Here is a blog post I did a while back on troubleshooting InnoDB on MySQL. I am on a mac, so a few things would be different if you are on windows, but otherwise the concepts are the same.
http://www.rimple.com/tech/2010/8/29...ot-be-you.html
Ken
-
Hi,
Here is the surefire-report of one of the Integration test
-------------------------------------------------------------------------------
Test set: com.foo.neoroo.domain.PersonIntegrationTest
-------------------------------------------------------------------------------
Tests run: 9, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.537 sec <<< FAILURE!
testMarkerMethod(com.foo.neoroo.domain.PersonInteg rationTest) Time elapsed: 0.048 sec <<< FAILURE!
junit.framework.AssertionFailedError: expected:<1> but was:<0>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:2 83)
at junit.framework.Assert.assertEquals(Assert.java:64 )
at junit.framework.Assert.assertEquals(Assert.java:19 5)
at junit.framework.Assert.assertEquals(Assert.java:20 1)
at com.foo.neoroo.domain.PersonIntegrationTest.testMa rkerMethod(PersonIntegrationTest.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runRefle ctiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallabl e.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExpl osively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod .evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements .RunBeforeTestMethodCallbacks.evaluate(RunBeforeTe stMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements .RunAfterTestMethodCallbacks.evaluate(RunAfterTest MethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements .SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.runChild(SpringJUnit4ClassRunner.jav a:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild( BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner. java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRu nner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentR unner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRu nner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRu nner.java:184)
at org.springframework.test.context.junit4.statements .RunBeforeTestClassCallbacks.evaluate(RunBeforeTes tClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements .RunAfterTestClassCallbacks.evaluate(RunAfterTestC lassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.ja va:236)
at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.run(SpringJUnit4ClassRunner.java:180 )
at org.apache.maven.surefire.junit4.JUnit4TestSet.exe cute(JUnit4TestSet.java:59)
at org.apache.maven.surefire.suite.AbstractDirectoryT estSuite.executeTestSet(AbstractDirectoryTestSuite .java:115)
at org.apache.maven.surefire.suite.AbstractDirectoryT estSuite.execute(AbstractDirectoryTestSuite.java:1 02)
at org.apache.maven.surefire.Surefire.run(Surefire.ja va:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.SurefireBooter.ru nSuitesInProcess(SurefireBooter.java:350)
at org.apache.maven.surefire.booter.SurefireBooter.ma in(SurefireBooter.java:1021)
---------------------------------------------------------
Here is the stack trace
2010-12-31 13:39:41,133 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtil s - Fetching JDBC Connection from DataSource
2010-12-31 13:39:41,164 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtil s - Registering transaction synchronization for JDBC Connection
2010-12-31 13:39:41,237 [main] TRACE org.hibernate.type.LongType - binding null to parameter: 1
2010-12-31 13:39:41,241 [main] TRACE org.hibernate.type.TimestampType - binding '2010-12-31 13:39:41' to parameter: 2
2010-12-31 13:39:41,250 [main] TRACE org.hibernate.type.TimestampType - binding '2010-12-31 13:39:41' to parameter: 3
2010-12-31 13:39:41,250 [main] TRACE org.hibernate.type.StringType - binding 'Onjon' to parameter: 4
2010-12-31 13:39:41,250 [main] TRACE org.hibernate.type.StringType - binding 'Shah' to parameter: 5
2010-12-31 13:39:41,250 [main] TRACE org.hibernate.type.IntegerType - binding '0' to parameter: 6
2010-12-31 13:39:41,263 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtil s - Returning JDBC Connection to DataSource
---------------------------
All my tables are using InnoDB storage engine
but still same problem.
-
Hi,
There is a update.
When I have changed from the below lines:
------------------------------------------------------
int count = jdbcTemplate.queryForInt("select count(0) from Person");
Assert.assertEquals(1, count);
------------------------------------------------------
to this line
-----------------------------------------------------
Assert.assertEquals(1, person.countPeople());
-----------------------------------------------------
my PersonIntegrationTest gets passed.
I have found this countPeople() method from Person_Roo_Entity.aj
public static long Person.countPeople() {
return entityManager().createQuery("select count(o) from Person o", Long.class).getSingleResult();
}
Any idea.
-
Ok, I think I see what is going on here.
Are you trying to verify data that is saved in a method using Jdbc? If so, are you doing a entityManager.flush() before you do your Jdbc query?
JPA / Hibernate use a session to cache all scheduled updates. Periodically, based on triggering events such as needing a server-side generated primary key for another entity's foreign key, or a commit, the context gets flushed automatically. That won't happen until those events happen, or you leave your transaction.
If you do a flush, your jdbc query will likely work. However, querying through the session, using the JPA entity objects, is the right way to verify, since you are looking at the same session data that eventually gets flushed, so your view of the data is the same as JPA. Plus, you don't have to do a flush.
Ken
-
Hi,
Thank you for your reply.
I have put the below line before jdbc query
Person.entityManager().flush();
but unfortunately it does not work.
Anyway as long as
Assert.assertEquals(1, person.countPeople());
works I am Ok.
-
Good. BTW, Is your test annotated with @Transactional?
-
Hi,
No, my test method does not have @Transactional annotation. But Person.persist() has @Transactional annotation. Anyway I have put the @Transactional annotation on my test method but it does not make any difference.