Generics and game platform

I use the Play Framework in the current version, and my model classes extend play.db.jpa.JPABase.

Today I tried to make the commonly used request type general and define a static helper method to create it.

I wrote the following:

import play.db.jpa.Model; import play.libs.F; public class GenericQueries { public static <T extends Model> F.Option<T> firstOption( Class<T> clazz, String query, Object... parameters){ final T queryResult = T.find(query,parameters).first(); return (queryResult == null) ? F.Option.<T>None() : F.Option.Some(queryResult); } } 

However, I get the following error:

Runtime exception

Unsupported OperationException: Please annotate your JPA model using the @ javax.persistence.Entity annotation.

I am debugging a method, at runtime T seems to be correctly set to the corresponding Model class. I even see the annotation.

I suspect some voodoo enhancing class is responsible for the players responsible for this, but I'm not quite sure.

Any ideas?

Update: added model class as requested

Here is an abridged version of one of the Model classes that I use.

 package models; import org.apache.commons.lang.builder.ToStringBuilder; import play.data.validation.Required; import play.db.jpa.Model; import play.modules.search.Field; import play.modules.search.Indexed; import javax.persistence.Column; import javax.persistence.Entity; import java.util.Date; @Entity @Indexed public class FooUser extends Model { @Required public Date firstLogin; @Field @Required(message = "needs a username") @Column(unique = false,updatable = true) public String name; @Field public String description; @Required public boolean isAdmin; @Override public String toString(){ return new ToStringBuilder(this) .append("name", name) .append("admin", isAdmin) .toString(); } } 
+4
source share
2 answers

In Play entites, you need to extend play.db.jpa.Model and use the @Entity annotation (class level).

What are you talking about, I understand that you are expanding play.db.jpa.JPABase.

This can be the cause of the problem, since Play (as you point out) dynamically improves classes and may interfere with your inheritance.

EDIT: I tested the problem

The problem is that Play does not improve the T. object. This means that the find method, called id, is one of the GenericModel (model's parent) whose implementation is to throw an exception with a message.

The amplifier seems to only detect classes with @Entity.

Even the mericano1 solution does not work, the enhancer does not select it. Therefore, I feel that you will not be able to use this method on Play.

+6
source

The best way to do this is to use a base class that extends play.db.jpa.Model only with static methods that will be used by subclasses.

Add the @Entity annotation to the base class and class fields.

 import play.db.jpa.Model; import play.libs.F; public class BaseModel extends Model { public static <T extends Model> F.Option<T> firstOption( Class<T> clazz, String query, Object... parameters){ final T queryResult = T.find(query,parameters).first(); return (queryResult == null) ? F.Option.<T>None() : F.Option.Some(queryResult); } } 

And then

 @Entity public class FooUser extends BaseModel { .... } 
+2
source

All Articles