У меня есть POJO структуру, подобную этойобъективизации Переводчик в JPA Attribute конвертер
@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, и ответ полезен (используйте Переводчик) и неполный (я не могу найти документацию о том, как использовать интерфейс Translator).
Две проблемы, то я столкнулся в настоящее время:
1) Нанести переводчик только к конкретным объектам (не сохраняя внедренный объект, но только идентификатор) и не все объекты, связанные с такого же рода.
С JPA этот запрос может быть сделан с использованием @Converter
аннотацию Итак, с этим проектом, класс должен быть чем-то вроде этого
@Entity
public class ClassA {
@Id
public Long id;
@MyCustomTranslator
public ClassB classbObject;
// Default behaviour
public ClassB embeddedObject;
}
мне нужно указать, что я не нужен гибридная настойчивость, переменная Java всегда будет сохраняться одинаково (встроенный или просто id), но мне нужно дифференцировать, если класс (например) имеет две переменные того же типа или у меня один и тот же тип переменной в 2 разных классы
2) В качестве альтернативы первого пункта, переместите решение в Translator it self, поэтому код «convert pojo to id» использует кодированные предположения, чтобы определить, должен ли объект быть сохранен по умолчанию или преобразовать его в значение ID.
Без документации я попытался подражать уже существующему Translator из исходного кода Objectify, но я не могу получить рабочий.
Это первая попытка я попытался
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;
}
}
}
Вот код, который я использую для инициализации
ObjectifyService.factory().getTranslators().add(new TestTranslator());
ObjectifyService.register(ClassA.class);
ObjectifyService.register(ClassB.class);
Это не работает, потому что я очень долго StackTrace во время init, с основной погрешностью
TestTranslator$CustomTranslator cannot be cast to com.googlecode.objectify.impl.translate.ClassTranslator
Кроме того, это не решение моей проблемы номер 1, поэтому я не могу решить, вставлять объект как обычно или применять мой переводчик.
Вторая попытка, с другой суперкласс Переводчик
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
Кажется, что объективизировать заставляет меня использовать 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) Даже если этот класс работает, я могу создать встроенный объект (с идентификатором внутри), и я не могу сохранить его как чистый Long (o List). Из-за этого часть индексации, которую я не уверен, может быть выполнена.
В конце, 2 вопроса: 1) Есть ли правильный Translator
для преобразования объекта класса в чистый id? 2) Как конвертер может применяться только к определенным переменным того же типа?