开发者

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 ...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜