简体   繁体   English

我可以在@MappedSuperclasses上创建静态方法吗?

[英]Can I create static methods on @MappedSuperclasses?

I have an abstract TemporalModel class (annotated with @MappedSuperclass ) that adds created and updated fields to all extending models. 我有一个抽象的TemporalModel类(使用@MappedSuperclass注释),它将createdupdated字段添加到所有扩展模型。 I want to add a getLatest() static method to it: 我想为它添加一个getLatest()静态方法:

public static TemporalModel getLatest() {
    return find("order by created").first();
}

When I put this method on the base class, and call it through a concrete class ( Transaction.getLatest() ), I get an error: 当我把这个方法放在基类上,并通过一个具体的类( Transaction.getLatest() )调用它时,我收到一个错误:

UnsupportedOperationException occured : Please annotate your JPA model with @javax.persistence.Entity annotation. 发生UnsupportedOperationException:请使用@ javax.persistence.Entity批注对JPA模型进行批注。

I suspect this is because JPA doesn't in fact know I'm calling this method "through" the base class (there is no real static method inheritance in Java). 我怀疑这是因为JPA实际上并不知道我正在通过基类调用这个方法(在Java中没有真正的静态方法继承)。

Is there another way to implement this method once, instead of repeating it on all entity classes? 是否有另一种方法来实现此方法一次,而不是在所有实体类上重复它?

Update - one way to achieve this (which I'm using in another heavier app) is described here ( gist ). 更新 - 这里描述实现此目的的一种方法(我在另一个较重的应用程序中使用)( gist )。 In my current app, however, I wouldn't like to use repositories, and I wondered if there's another, lighter solution. 然而,在我当前的应用程序中,我不想使用存储库,我想知道是否还有另一个更轻的解决方案。

Constructors and static methods can never be abstract. 构造函数和静态方法永远不可能是抽象的。 The idea behind an abstract class is to create blueprints of methods, that have to get worked out in the subclass(es). 抽象类背后的想法是创建方法的蓝图,必须在子类中得到解决。 I suggest trying an interface TemporalModel instead of an abstract class, in which you create the method public static TemporalModel getLatest(); 我建议尝试一个接口TemporalModel而不是一个抽象类,在其中创建方法public static TemporalModel getLatest();

I haven't used this Play framework, so I'm not sure about the details here, but usually, when one does the stuff you want to do, in Java, one simply specifies the concrete class as a parameter to the static method in question. 我没有使用过这个Play框架,所以我不确定这里的细节,但通常情况下,当你想要做的事情,在Java中,只需将具体类指定为静态方法的参数。题。 It's kind of ugly, of course, but it is Java. 当然,这有点难看,但它是Java。

I assume that this find method is a static method that is added somehow (by annotation processing?) by this framework on every extending class, right? 我假设这个find方法是一个静态方法,通过这个框架在每个扩展类上以某种方式(通过注释处理?)添加,对吧? In that case, I think your only recourse is to do something like this: 在这种情况下,我认为你唯一的办法是做这样的事情:

public static <T extends TemporalModel> T getLatest(Class<T> cl) {
    try {
        /* I don't know what type the find() method returns, so you'll have to fix the casting */
        return(cl.cast(cl.getMethod("find", String.class).invoke("order by created").first()));
    } catch(AllThosePeskyReflectionExceptions e) {
        throw(new Error(e));
    }
}

I think that's the best way available given the premises. 我认为这是最好的方式。 I know it's ugly, so I'd be happy to be wrong. 我知道这很难看,所以我很乐意做错。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM