当超类不是@Entity

时间:2015-10-22 14:40:23

标签: java google-app-engine objectify

TL; DR: 当属性派生自非@Entity超类时,是否可以将@Index设置为Objectify实体属性。

长版:

Java项目包含应用程序使用的抽象模型类,而不是具体对象(Objectify实体)。对于每个这样的模型,存在一个@Entity,它扩展了模型并添加了持久层(Objectify)的细节。

一个简单的例子:

public abstract class UserModel {
  protected String givenName;
}

@Entity
public class UserImpl extends UserModel {
  @Id
  private Long id;
}

我选择这种方法是因为我想独立于持久层使用模型类。因此,模型类不能包含持久层特定的注释或代码。

我知道在Morphia(MongoDB ORM)中可以像这样注释一个@Entity类:

@Indexes(@Index(value = "superGivenName", fields = {@Field("givenName")}))

是否有可能在Objectify中达到类似的效果?它不一定是带注释的解决方案。但是,应该可以将解决方案封装在@Entity类中。

注意:我会发布一个可能的解决方案,但我正在寻找更具风格/美感的东西,所以当你有更好的想法时,请不要犹豫回答。

2 个答案:

答案 0 :(得分:1)

我认为你不会找到满足你的答案。 Objectify不提供任何类似内置的行为。

我假设你担心Objectify注释泄漏到你将广泛分发的客户端jar(android或某种rpc)。我强烈建议为您的API创建单独的模型类,原因很简单,它会将您的数据模型(将更改)与您的API分离(这可能会在不同的计划中发生变化)。在现场升级客户很困难。使用单独的类,您可以使用IDE重构数据模型,而无需担心向后兼容性。

如果使用http://projectlombok.org,数据传输对象中几乎没有样板文件。

答案 1 :(得分:0)

一种可能的解决方案是隐藏应该在@Entity类中编入索引的超类属性。然后使用@OnLoad和@OnSave生命周期回调在父类和子类之间传播值。

示例:

public abstract class UserModel {
  protected String givenName;
}

@Entity
public class UserImpl extends UserModel {
  @Id
  private Long id;
  @Index
  private String givenName;
  @OnLoad
  void onLoad(){
      super.givenName = this.givenName;
  }
  @OnSave
  void onSave(){
      this.givenName = super.givenName;
  }
}