我有像这样的POJO结构
@Entity
public class ClassA {
@Id
public Long id;
public ClassB classbObject;
}
另一个班级
@Entity
public class ClassB {
@Id
public Long id;
public String fieldA;
public String fieldB;
}
现在,基于自定义条件,我需要将classbObject
保存为嵌入式(Objectify的默认行为)或仅保存id属性(此处为Translator
)。
即使使用单个字段ClassA
或多个字段List<ClassA>
如果对象将被保存为ID,我还需要对其进行索引以对其进行查询。
我已经在Objectify board上询问了回复是否有用(使用翻译器)并且不完整(我无法找到有关如何使用翻译器界面的任何文档)。
我现在面临的两个问题是:
1)仅将翻译器应用于特定对象(不保存嵌入对象,只保存id),而不是所有与同类对象相关的对象。
使用JPA,可以使用@Converter
注释进行此请求
所以,通过这种设计,类应该是这样的
@Entity
public class ClassA {
@Id
public Long id;
@MyCustomTranslator
public ClassB classbObject;
// Default behaviour
public ClassB embeddedObject;
}
我需要指定我不需要混合持久性,Java变量将始终以相同的方式保存(嵌入或只是id),但我需要区分是否类(例如)两个相同类型的变量或我在2个不同类中具有相同的变量类型
2)除了第一点之外,在译者本身中移动决定,所以&#34;将pojo转换为id&#34;代码使用编码假设来确定对象是否应存储为默认嵌入或将其转换为ID值。
没有文档我试图从Objectify源代码中模拟已经存在的Translator,但是我无法使用它。
这是我尝试的第一次尝试
public class TestTranslator implements TranslatorFactory<ClassA, Long> {
@Override
public Translator<ClassA, Long> create(TypeKey<ClassA> arg0, CreateContext arg1, Path arg2) {
return new CustomTranslator();
}
public static class CustomTranslator implements Translator<ClassA, Long> {
@Override
public ClassA load(Long arg0, LoadContext arg1, Path arg2) throws SkipException {
ClassA a = new ClassA();
a.id = arg0;
// Other custom code
return a;
}
@Override
public Long save(ClassA arg0, boolean arg1, SaveContext arg2, Path arg3) throws SkipException {
return arg0.id;
}
}
}
以下是我用于init的代码
ObjectifyService.factory().getTranslators().add(new TestTranslator());
ObjectifyService.register(ClassA.class);
ObjectifyService.register(ClassB.class);
这不起作用,因为我在init期间得到一个非常长的堆栈跟踪,主错误
TestTranslator$CustomTranslator cannot be cast to com.googlecode.objectify.impl.translate.ClassTranslator
另外,这不是解决我的第一个问题,所以我无法决定是否将对象嵌入正常或应用我的翻译。
第二次尝试,与另一个超级类翻译
public class TestValueTranslator extends ValueTranslatorFactory<ClassA, Long> {
public TestValueTranslator() {
super(ClassA.class);
}
@Override
protected ValueTranslator<ClassA, Long> createValueTranslator(TypeKey<ClassA> tk, CreateContext ctx, Path path) {
return new ValueTranslator<ClassA, Long>(Long.class) {
@Override
protected ClassA loadValue(Long value, LoadContext ctx, Path path) throws SkipException {
ClassA a = new ClassA();
a.id = value;
// Other custom code
return a;
}
@Override
protected Long saveValue(ClassA value, boolean index, SaveContext ctx, Path path) throws SkipException {
return value.id;
}
};
}
}
与上述相同的错误
TestValueTranslator$1 cannot be cast to com.googlecode.objectify.impl.translate.ClassTranslator
似乎Objectify强迫我使用ClassTranslator,我试图实施
public class TestClassTranslatorFactory extends ClassTranslatorFactory<ClassA> {
@Override
public ClassTranslator<ClassA> create(TypeKey<ClassA> tk, CreateContext ctx, Path path) {
// ????
return super.create(tk, ctx, path);
}
public class TestClassTranslator extends ClassTranslator<ClassA> {
public TestClassTranslator(Class<ClassA> declaredClass, Path path, Creator<ClassA> creator, Populator<ClassA> populator) {
super(declaredClass, path, creator, populator);
}
@Override
public ClassA loadSafe(PropertyContainer arg0, LoadContext arg1, Path arg2) throws SkipException {
EmbeddedEntity e = (EmbeddedEntity) arg0;
Long id = (Long) e.getProperty("id");
ClassA a = new ClassA();
a.id = id;
// Other custom code
return a;
}
@Override
public PropertyContainer saveSafe(ClassA arg0, boolean arg1, SaveContext arg2, Path arg3) throws SkipException {
EmbeddedEntity e = new EmbeddedEntity();
e.setProperty("id", arg0.id);
return e;
}
}
}
这里有两个问题:
1)我无法理解如何在TestClassTranslator
构造函数中创建TestClassTranslatorFactory
对象。
2)即使这个类有效,我强制创建一个嵌入的实体(内部有id),我不能保存为纯Long(o List)。因此,索引部分I不确定是否可以完成。
最后,有两个问题:
1)是否有正确的Translator
将类对象转换为纯id?
2)转换器如何仅应用于相同类型的某些变量?
答案 0 :(得分:1)
这里有很多内容,stackoverflow可能是来回对话的一种糟糕的格式,最终会让你到达你想去的地方。有google group可能会更有用。
您的第一个问题是TranslatorFactory
的合同要求create()
如果TypeKey
不适合该工厂,则返回null。在注册时,工厂按顺序进行试验,直到其中一个成功; Translator
然后成为快速但静态的元模型的一部分,用于在POJO和实体之间进行转换。通过总是返回翻译,你在这个发现期间“声称”一切。因此,检查类型是否正确,如果类型不适合您,则返回null。
另一个有用的知识是有一个@Translate
注释可以在特定字段上使用,这将强制它们由特定的翻译器处理。您可以将此项用于未事先注册的工厂,这样您就可以有选择地修改某些字段的行为,而不会影响该类型的其他用途。
答案 1 :(得分:0)
使用可应用于特定字段的@Translate
解决