How to inherit a model from a superclass in playframework

I'm trying to understand how inheritance works in a game! But so far unsuccessfully.

So I have such a superclass:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) abstract class SuperClass extends Model { @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "SEQ_TABLE") @TableGenerator(name = "SEQ_TABLE") Long id; int testVal; } 

And 2 inherited classes:

 @Entity public class Sub extends SuperClass { String name; @Override public String toString() { return name; } } @Entity public class Sub1 extends SuperClass { String name; @Override public String toString() { return name; } } 

Also I have 2 controllers for inherited classes:

 public class Subs and Sub1s extends CRUD { } 

After starting the application, I get 2 tables in MySQL db for my models (Sub and Sub1) with the following structure: id bigint (20), name varchar (255). Without testVal , which is in the superclass.

And when I try to create a new object of the Sub class in the CRUD interface, I get this error: A runtime error occurred in the template {module: crud} /app/views/tags/crud/form.html. The exception was MissingPropertyException: There is no such property: testVal for the class: models.Sub.

In {module: crud} /app/views/tags/crud/form.html (near line 64) # {crud.numberField name: field.name, value: (currentObject? CurrentObject [field.name]: null) /}

  • What should I do to correctly generate MySQL tables for legacy models and fix the error?
  • Is it possible to have one super controller for multiple inherited classes?
+6
source share
2 answers

Well, thanks to sdespolit , I did some experiments. And here is what I have:

superclass:

 @MappedSuperclass @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class SuperClass extends Model { } 

Inherited class:

 @Entity public class Sub extends SuperClass { } 

The "supercontroller" I did like this:

 @With({Secure.class, SuperController.class}) @CRUD.For(Sub.class) public class Subs extends CRUD { } @With({Secure.class, SuperController.class}) @CRUD.For(Sub1.class) public class Sub1s extends CRUD { } 

@ CRUD.For (Sub.class) is used to tell interceptors which classes it should work with

 public class SuperController extends Controller { @After/Before/Whatever public static void doSomething() { String actionMethod = request.actionMethod; Class<? extends play.db.Model> model = getControllerAnnotation(CRUD.For.class).value(); List<String> allowedActions = new ArrayList<String>(); allowedActions.add("show"); allowedActions.add("list"); allowedActions.add("blank"); if (allowedActions.contains(actionMethod)) { List<SuperClass> list = play.db.jpa.JPQL.instance.find(model.getSimpleName()).fetch(); } } } 

I'm not sure that the doSomething () approach is really nice and the Java / Play style! -style. But it works for me. Please tell me if you can find out the model class in a more native way.

+2
source

"and a table for each class is an optional feature of the JPA specification, so not all providers can support it" from the WikiBook .

Why aren't you using @MappedSuperclass? In addition, you must extend the GenericModel. In your example, you have identified the identifier twice, which may also be the cause of your problem.

+1
source

Source: https://habr.com/ru/post/901307/


All Articles