Hi:
I'm try to using play! famework to develop same prototype project. And
feel good.
I have an awkward question about using dbunit framework (DBTestCase)
to test jpa module layer code in play! . As we know this unit test is
drived by java code rather than drived by "play test XXX" or
"
http://localhost:9000/@tests".
When I run my test case in eclipse by junit plugin (right click menu)
I got exception like this. ("blog sample" project):
javax.persistence.PersistenceException:
org.hibernate.PropertyAccessException: could not get a field value by
reflection getter of models.Post.comments
at
org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException
(AbstractEntityManagerImpl.java:614)
at
org.hibernate.ejb.AbstractEntityManagerImpl.persist
(AbstractEntityManagerImpl.java:226)
at play.db.jpa.JPASupport.save(JPASupport.java:118)
at
unit.jpamodels.PostTestCase.testPostSave(PostTestCase.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at
org.junit.internal.runners.JUnit38ClassRunner.run
(JUnit38ClassRunner.java:81)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run
(JUnit4TestReference.java:45)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run
(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests
(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests
(RemoteTestRunner.java:673)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run
(RemoteTestRunner.java:386)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main
(RemoteTestRunner.java:196)
Caused by: org.hibernate.PropertyAccessException: could not get a
field
value by reflection getter of models.Post.comments
at
org.hibernate.property.DirectPropertyAccessor$DirectGetter.get
(DirectPropertyAccessor.java:58)
at
org.hibernate.property.DirectPropertyAccessor$DirectGetter.getForInsert
(DirectPropertyAccessor.java:63)
at
org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValuesToInsert
(AbstractEntityTuplizer.java:294)
at
org.hibernate.tuple.entity.PojoEntityTuplizer.getPropertyValuesToInsert
(PojoEntityTuplizer.java:239)
at
org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValuesToInsert
(AbstractEntityPersister.java:3696)
at
org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate
(AbstractSaveEventListener.java:290)
at
org.hibernate.event.def.AbstractSaveEventListener.performSave
(AbstractSaveEventListener.java:204)
at
org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId
(AbstractSaveEventListener.java:144)
at
org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId
(EJB3PersistEventListener.java:49)
at
org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient
(DefaultPersistEventListener.java:154)
at
org.hibernate.event.def.DefaultPersistEventListener.onPersist
(DefaultPersistEventListener.java:110)
at
org.hibernate.event.def.DefaultPersistEventListener.onPersist
(DefaultPersistEventListener.java:61)
at
org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:645)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:619)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:623)
at
org.hibernate.ejb.AbstractEntityManagerImpl.persist
(AbstractEntityManagerImpl.java:220)
... 21 more
Caused by: java.lang.IllegalArgumentException: Can not set
java.util.List field models.Post.comments to models.Post
at
sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException
(Unknown
Source)
at
sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException
(Unknown
Source)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(Unknown Source)
at java.lang.reflect.Field.get(Unknown Source)
at
org.hibernate.property.DirectPropertyAccessor$DirectGetter.get
(DirectPropertyAccessor.java:55)
... 36 more
I'm test case code at below. "JpaModelsTestCase" base class use to
init
dbunit env. And "PostTestCase" is to test jpa method like save.
1. At JpaModelsTestCase class constructor I have init & start play!
and
call startTx to create jpa session.
2. The "post.save()" in "testPostSave" mehod is KEY question point.
package unit.jpamodels;
import java.io.File;
import org.dbunit.DBTestCase;
import org.dbunit.PropertiesBasedJdbcDatabaseTester;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.ext.oracle.OracleDataTypeFactory;
import play.Play;
public abstract class JpaModelsTestCase extends DBTestCase {
public JpaModelsTestCase(String name) throws Exception {
super(name);
System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS,
"oracle.jdbc.driver.OracleDriver");
System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL,
"jdbc:oracle:thin:@127.0.0.1:1521:ORACLE");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME,
"local");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD,
"local");
// Note that for Oracle you must specify the schema name
in uppercase.
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_SCHEMA,
"LOCAL");
// Run play! framework and initialize JPA context.
Play.init(new
File("C:/play-1.0-stable6/play_blog_sample"), "");
Play.start();
play.db.jpa.JPAPlugin.startTx(false);
}
@Override
protected void setUpDatabaseConfig(DatabaseConfig config) {
// Enable the qualified table names feature for oracle.
config.setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
// Skip Oracle 10g Recyclebin tables.
config.setFeature
(DatabaseConfig.FEATURE_SKIP_ORACLE_RECYCLEBIN_TABLES,
true);
// Setup oracle 10g data type factory.
config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new
OracleDataTypeFactory());
}
package unit.jpamodels;
import java.io.FileInputStream;
import models.Post;
import org.dbunit.Assertion;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Test;
public class PostTestCase extends JpaModelsTestCase {
public PostTestCase() throws Exception {
super("PostTest");
}
@Override
protected IDataSet getDataSet() throws Exception {
return new FlatXmlDataSet(new FileInputStream(
"test/unit/jpamodels/blog_empty.xml"));
}
@Override
protected DatabaseOperation getSetUpOperation() throws Exception
{
return DatabaseOperation.CLEAN_INSERT;
}
@Override
protected DatabaseOperation getTearDownOperation() throws
Exception {
return DatabaseOperation.DELETE_ALL;
}
@Test
public void testPostSave() throws Exception {
Post post = new Post("testPostTitle1",
"testPostContent1");
post.save();
IDataSet dbDataSet = getConnection().createDataSet();
ITable dbTable = dbDataSet.getTable("
LOCAL.POST");
IDataSet xmlDataSet = new FlatXmlDataSet(new
FileInputStream(
"/test/unit/jpamodels/expected_post_save.xml"));
ITable expectedTable =
xmlDataSet.getTable("
LOCAL.POST");
Assertion.assertEquals(expectedTable, dbTable);
}
}
I had try to use eclipse/junit plugin to run sample unit test case.
But
return exception: "The JPA context is not initialized." (at
JPA.java(18)). I can run test case by "play test XXX" &
"
http://localhost:9000/@tests" only??
How can I run unit test by unit test case java code in eclipse/junit
directly??
I need help, please! thank you very much.
btw
https://bugs.launchpad.net/play/+bug/276762/+viewstatus
who can tell me, Guillaume Bor how to fix this.
MORE DETAIL thks.