Morphia-MongoDB - "Please override this method for user marked Id field entity"
I am following a tutorial mention on code.google, but my example fails giving the following trace :
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.google.code.morphia.mapping.MappedClass.callLifecycleMethods(MappedClass.java:323)
at com.google.code.morphia.mapping.Mapper.toDBObject(Mapper.java:371)
at com.google.code.morphia.DatastoreImpl.entityToDBObj(DatastoreImpl.java:674)
at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:722)
at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:802)
at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:796)
at models.com.vlist.activity.classes.TestMongoData.testUserData(TestMongoData.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
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(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.google.code.morphia.mapping.MappedClass.callLifecycleMethods(MappedClass.java:304)
... 28 more
Caused by: java.lang.UnsupportedOperationException: Please override this method for user marked Id field entity: models.com.vlist.activity.classes.User
at play.modules.morphia.Model.setId_(Model.java:284)
at play.modules.morphia.Model.generateId_(Model.java:299)
... 33 more
My example is as following:
import javax.persistence.Entity;
import org.bson.types.ObjectId;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.Morphia;
import com.google.code.morphia.annotations.Id;
import play.modules.morphia.Model;
@Entity
public class User extends Model {
@Id ObjectId id;
private String firstName;
private String lastName;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName(){
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
}
and
import static org.junit.Assert.*;
import org.junit.Test;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.Morphia;
public class TestMongoData {
@Test
public void testUserData() {
User user = new User();
user.setFirstName("first");
user.setLastName("last");
Morphia morphia = new Morphia();
Datastore ds = morphia.createDatastore("testData");
ds.save(user);
}
}
What could be wrong?
Update:
When I use play test
, i see the following:
08:01:55,783 ERROR ~
@66h1bm10d
Internal Server Error (500) for request GET /@tests
Compilation error (In {module:morphia}/app/morphia/Filter.java around line 8)
The fil开发者_JAVA技巧e {module:morphia}/app/morphia/Filter.java could not be compiled. Error raised is : The type Filter is already defined
play.exceptions.CompilationException: The type Filter is already defined
at play.classloading.ApplicationCompiler$2.acceptResult(ApplicationCompiler.java:246)
at org.eclipse.jdt.internal.compiler.Compiler.handleInternalException(Compiler.java:672)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:516)
at play.classloading.ApplicationCompiler.compile(ApplicationCompiler.java:278)
at play.classloading.ApplicationClassloader.getAllClasses(ApplicationClassloader.java:406)
at play.Play.start(Play.java:453)
at play.Play.detectChanges(Play.java:574)
at play.Invoker$Invocation.init(Invoker.java:186)
at Invocation.HTTP Request(Play!)
The problem comes from your @Entity definition. You're using JPA annotation while you should use the Morphia ones.
On startup, the Morphia plugin will retrieve all classes marked with the morphia Entity annotation and enhance them with various injected model methods. You're receiving this exception because your model class hasn't been enhanced.
If you annotate @Id then play morphia won't enhance your model by providing right implementation for void setId_(Object id) method. Try defining one yourself like this.
@Entity
class User extends Model {
@Id String email;
protected void setId_(Object id) {
}
}
Try removing the @Id ObjectId id;
from your model. The Morphia Module for Play Framework will add the id for you.
Then make the fields public and remove the getter/setter methods.
public String firstName;
public String lastName;
Also, your Entity import is incorrect. Try this
import com.google.code.morphia.annotations.Entity;
Try this for a test case:
import static org.junit.Assert.*;
import org.junit.Test;
import play.test.UnitTest;
public class TestMongoData extends UnitTest {
@Test
public void testUserData() {
User user = new User();
user.setFirstName("first");
user.setLastName("last");
user.save();
}
}
It's seems that you have defined the morphia module in the dependency file and in the application conf file.
In the dependencies file : - play -> morphia [1.2.1beta6,)
In the application conf file : module.morphia=${play.path}/modules/morphia
You must removed one of this declaration otherwise the morphia module is loaded twice ...
精彩评论