【问题标题】:How to inherit a model from superclass in playframework如何从playframework中的超类继承模型
【发布时间】:2011-12-27 04:13:25
【问题描述】:

我试图了解继承是如何发挥作用的!但还没有成功。

所以,我有这样的超类:

@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;
}

还有2个继承类:

@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;
    }
}

我还有 2 个用于继承类的控制器:

public class Subs and Sub1s extends CRUD {

}

应用程序启动后,我在 MySQL 数据库中为我的模型(Sub 和 Sub1)收到了 2 个具有以下结构的表:id bigint(20), name varchar( 255)。没有超类中的 testVal

当我尝试在 CRUD 接口中创建 Sub 类的新对象时,我收到这样的错误: 模板 {module:crud}/app/views/tags/crud/form.html 中发生执行错误。引发的异常是 MissingPropertyException : No such property: testVal for class: models.Sub.

在 {module:crud}/app/views/tags/crud/form.html 中(大约第 64 行) #{crud.numberField name:field.name, value:(currentObject ? currentObject[field.name] : null) /}

  1. 如何正确生成继承模型的 MySQL 表并修复错误?
  2. 是否可以为多个继承的类使用一个超级控制器?

【问题讨论】:

  • 请注意,您使用默认访问修饰符声明您的字段。将其更改为公开,以便播放 PropertiesEnhaner 可以完成它的工作。
  • 谢谢。我添加了对Long idint testVal 的公共访问权限。现在我可以在 CRUD 界面中看到 testVal 字段,并且可以正确保存模型。但是MySql中仍然没有这个字段,所以我无法保存这个值。我认为我应该为这个值添加某种注释,但是什么?
  • 最后,我找到了解决方案:我刚刚将@MappedSuperclass 添加到SuperClass 并从中删除了Long idsdespolit,如何接受您添加公共访问中间件的建议?我找不到任何接受按钮。
  • 您不能接受 cmets。但是您可以编写自己的答案来总结所有内容。我不会反对。
  • 顺便说一句,请确保您了解策略 docs.jboss.org/hibernate/stable/annotations/reference/en/html/… 的缺点。此外,我还测试了您的架构(如您的第一条评论但没有 id) - 它在 postgresql 中运行良好。

标签: java jpa playframework superclass


【解决方案1】:

好吧,感谢 sdespolit,我做了一些实验。这就是我所拥有的:

超类:

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

继承类:

@Entity 
public class Sub extends SuperClass {
}

我这样制作的“超级控制器”:

@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) 用于告诉拦截器应该使用哪个类

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();
        }
    }
}

我不确定 doSomething() 方法是否真的很好,并且是 Java 风格/Play! 风格。但它对我有用。 请告诉我是否有可能以更原生的方式捕捉模型的类。

【讨论】:

    【解决方案2】:

    “每个类的表是 JPA 规范的可选功能,因此并非所有提供者都支持它”来自WikiBook

    为什么不使用@MappedSuperclass?此外,您应该扩展 GenericModel。在您的示例中,您定义了 id 两次,这也可能是您出现问题的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      • 2013-05-01
      • 1970-01-01
      • 2019-10-04
      相关资源
      最近更新 更多