Ответ 1
Это возможно, вам нужно использовать @NamedEntityGraph,
Это должно помочь, http://www.thoughts-on-java.org/jpa-21-entity-graph-part-1-named-entity/
У меня есть объект, которому принадлежит другой объект:
//psuedocode
public class ClassA{
private String name;
@OneToOne
private ClassB classb;
}
public class ClassB{
private String thing1;
private String thing2;
private String thing3;
}
Когда я извлекаю объекты ClassA, я не хочу видеть ClassB.thing3, но я хочу видеть вещь1 и вещь 2:
{
"name":"classa",
"classb":{
"thing1":"hi",
"thing2":"there"
}
}
Но если я запрашиваю для ClassB, я хочу видеть все:
{"thing1":"hi",
"thing2":"there",
"thing3":"joseph"}
Поэтому я не могу просто поместить аннотацию ignore поверх thing3, потому что тогда я проигнорирую ее во второй выборке. Я попробовал Converter<ClassB>
, но это заставило меня реализовать toString()
и fromString()
для JSON, который умирает при преобразовании объекта JSON на Java-сторону (конвертер ожидает String, но вместо этого получает объект).
Я хочу избежать сборки/разбора объекта JSON самостоятельно, если это возможно, чтобы мой поставщик json выполнял работу, если это было возможно. Я нахожусь на Джонсоне.
Это возможно, вам нужно использовать @NamedEntityGraph,
Это должно помочь, http://www.thoughts-on-java.org/jpa-21-entity-graph-part-1-named-entity/
Что-то вроде этого должно быть возможным путем запроса с помощью SELECT NEW, но вам понадобятся новые классы для этого... и не будут передавать ваши сущности непосредственно в JSON.
новые классы: (Псевдокод)
class ResultB {
String thing1;
String thing2;
public ResultB(ClassB classB) {
this.thing1 = classB.thing1;
this.thing2 = classB.thing2;
}
}
class ResultA {
String name;
ResultB resultB;
public ResultA(ClassA classA) {
this.name=classA.name;
this.resultB=new ResultB(classA);
}
}
Query:
select new ResultA(a) from ClassA a fetch join a.classB;
Затем вы можете передать ResultA вместо ClassA в JSON.
PS: Как уже упоминалось в комментарии выше, я не думаю, что NamedEntityGraphs - это путь сюда
Я бы всегда извлекал все данные из базы данных и позволял фильтрацию выполнять поставщик JSON, если вы все равно его сериализуете. Если вы используете Джексон, вы можете просто добавить представления в свои поля:
public class ClassA {
@JsonView(Views.AlwaysInclude.class)
private String name;
@JsonView(Views.AlwaysInclude.class)
@OneToOne
private ClassB classb;
}
public class ClassB {
@JsonView(Views.AlwaysInclude.class)
private String thing1;
@JsonView(Views.AlwaysInclude.class)
private String thing2;
private String thing3;
}
public class Views {
public static class AlwaysInclude {
}
}
Позже, когда вы сериализуете свой объект, вам просто нужно использовать ваше представление:
String result = mapper
.writerWithView(Views.AlwaysInclude.class)
.writeValueAsString(new ClassA());
Если вы хотите сериализовать только ClassB, вы не должны использовать представления.
String result = mapper.writeValueAsString(new ClassB());