Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inherit a model from superclass in playframework

I'm trying to understand how does the inheritance work in play! But unsuccessfully yet.

So, I have such 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 application was started, I recieve 2 tables in MySQL db for my models (Sub and Sub1) with such structure: id bigint(20), name varchar(255). Without testVal which is in superclass.

And when I try to create new object of Sub class in CRUD interface I recieve such error: Execution error occured in template {module:crud}/app/views/tags/crud/form.html. Exception raised was MissingPropertyException : No such property: testVal for class: models.Sub.

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

  1. What should I do to generate MySQL tables for inherited models properly and fix the error?
  2. Is it possible to have a single superController for several inherited classes?
like image 594
gl0om Avatar asked Nov 11 '11 16:11

gl0om


1 Answers

Well, thanks to sdespolit, I've made some experiments. And here is what I've got:

Superclass:

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

Inherited class:

@Entity 
public class Sub extends SuperClass {
}

"Super Controller" I made in such way:

@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 the interceptors with what class it should work

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 about doSomething() approach is truly nice and Java-style/Play!-style. But it works for me. Please tell me if it's possible to catch out the model's class in more native way.

like image 195
gl0om Avatar answered Sep 24 '22 08:09

gl0om