Hello,
I'm getting duplicated rows on the database when testing my DAOs but if I flush the EntityManager manually I get only one.
The base Test class:
Code:
public abstract class IntegrationDAOTest {
protected EntityManagerFactory emf;
protected EntityManager em;
protected EntityTransaction tx;
protected String dataSetLocation;
protected List<DatabaseOperation> beforeTestOperations = new ArrayList<DatabaseOperation>();
protected List<DatabaseOperation> afterTestOperations = new ArrayList<DatabaseOperation>();
private ReplacementDataSet dataSet;
protected abstract void prepareSettings();
public IntegrationDAOTest() {
URL loggerPropertiesURL = this.getClass().getResource("/logger.properties");
PropertyConfigurator.configure(loggerPropertiesURL.getFile());
}
@SuppressWarnings("deprecation")
@BeforeClass(groups = {"integration"})
protected void prepareDataSet() throws Exception {
this.emf = Persistence.createEntityManagerFactory("eukleia-entity-dao-test");
this.em = emf.createEntityManager();
this.tx = em.getTransaction();
prepareSettings();
if (dataSetLocation == null)
throw new RuntimeException("Test subclass needs to prepare a datase location!");
InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream(dataSetLocation);
dataSet = new ReplacementDataSet(new FlatXmlDataSet(input));
dataSet.addReplacementObject("[NULL]", null);
}
@AfterClass(groups = {"integration"})
protected void closeEntityManagerFactory() {
if(this.em != null)
this.em.close();
if (this.emf != null)
this.emf.close();
}
@BeforeMethod(groups = "integration")
protected void beforeTestMethod() throws Exception {
prepareSettings();
for (DatabaseOperation op : beforeTestOperations ) {
op.execute(getConnection(), dataSet);
}
}
@AfterMethod(groups = "integration")
protected void afterTestMethod() throws Exception {
for (DatabaseOperation op : afterTestOperations ) {
op.execute(getConnection(), dataSet);
}
}
@SuppressWarnings("deprecation")
protected IDatabaseConnection getConnection() throws Exception {
Connection connection = ((org.hibernate.ejb.HibernateEntityManager) em).getSession().connection();
connection.prepareStatement("set FOREIGN_KEY_CHECKS=0").execute();
DatabaseConnection databaseConnection = new DatabaseConnection(connection);
DatabaseConfig config = databaseConnection.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory());
return databaseConnection;
}
}
If I execute the
persistNewComment() test method I have 3 identical rows added to the database. The first line is added when
u = userDAO.makePersistent(u) is called, the second one when
p = pageReviewDAO.makePersistent(p) is called and the third is added when
tx.commit() inside the
startNewTransaction method is called.
Comment test class:
Code:
public class CommentDAOTest extends IntegrationDAOTest implements IntegrationDAOTestInterface {
private CommentDAO commentDAO;
private PageReviewDAO pageReviewDAO;
private CategoryDAO categoryDAO;
private UserDAO userDAO;
@Override
protected void prepareSettings() {
dataSetLocation = "basedata-review.xml";
beforeTestOperations.add(DatabaseOperation.CLEAN_INSERT);
}
@Override
@BeforeMethod(groups = {"integration"})
public void startTransaction() {
em = emf.createEntityManager();
commentDAO = new CommentDAOBean();
pageReviewDAO = new PageReviewDAOBean();
categoryDAO = new CategoryDAOBean();
userDAO = new UserDAOBean();
commentDAO.setEntityManager(em);
categoryDAO.setEntityManager(em);
pageReviewDAO.setEntityManager(em);
userDAO.setEntityManager(em);
tx = em.getTransaction();
tx.begin();
}
@Override
@AfterMethod(groups = {"integration"})
public void commitTransaction() {
if (tx != null)
tx.commit();
}
@Override
public void startNewTransaction() {
tx.commit();
em = emf.createEntityManager();
commentDAO.setEntityManager(em);
categoryDAO.setEntityManager(em);
pageReviewDAO.setEntityManager(em);
userDAO.setEntityManager(em);
tx = em.getTransaction();
tx.begin();
}
@Test(groups = {"integration"})
public void persistNewComment() {
PageReview p = pageReviewDAO.findById(new Long(1), true);
Category c = categoryDAO.findById(new Long(2), true);
User u = userDAO.findById(new Long(3), true);
Comment co = new Comment("Comment 999", u, c, new Date());
p.addComment(co);
c.addComment(co);
u.addComment(co);
// em.flush();
u = userDAO.makePersistent(u);
p = pageReviewDAO.makePersistent(p);
startNewTransaction();
User su = userDAO.findById(new Long(3), true);
assert su.getComments().size() == 1;
}
}
Now if I remove the comment and
em.flush() is called before
u = userDAO.makePersistent(u) I get just one row added to the database.
Thank you!
Luiz Filipe