我正在使用 Spring Boot 1.5.1 和 Spring Data Release Ingalls。
KeyValueRepository 不适用于继承。它使用每个已保存对象的类名来查找相应的键值存储。例如。 save(new Foo()) 将保存的对象放在Foo 集合中。而abstractFoosRepo.findAll() 将在AbstractFoo 集合中查找,并且找不到任何Foo 对象。
这是使用 MongoRepository 的工作代码:
Application.java
默认 Spring Boot 应用程序启动器。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
AbstractFoo.java
我已经测试了include = JsonTypeInfo.As.EXISTING_PROPERTY 和include = JsonTypeInfo.As.PROPERTY。两者似乎都可以正常工作!
甚至可以使用自定义 JacksonModule 注册 Jackson 子类型。
重要提示: 强烈推荐@RestResource(path="abstractFoos")。否则_links.self 链接将指向/foos 和/bars 而不是/abstractFoos。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Foo.class, name = "MY_FOO"),
@JsonSubTypes.Type(value = Bar.class, name = "MY_Bar")
})
@Document(collection="foo_collection")
@RestResource(path="abstractFoos")
public abstract class AbstractFoo {
@Id public String id;
public abstract String getType();
}
AbstractFooRepo.java
这里没什么特别的
public interface AbstractFooRepo extends MongoRepository<AbstractFoo, String> { }
Foo.java & Bar.java
@Persistent
public class Foo extends AbstractFoo {
@Override
public String getType() {
return "MY_FOO";
}
}
@Persistent
public class Bar extends AbstractFoo {
@Override
public String getType() {
return "MY_BAR";
}
}
FooRelProvider.java
- 如果没有这部分,对象的输出将被分隔在
_embedded.foos 和_embedded.bars 下的两个数组中。
-
supports 方法确保对于扩展 AbstractFoo 的所有类,对象将被放置在 _embedded.abstractFoos 中。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class FooRelProvider extends EvoInflectorRelProvider {
@Override
public String getCollectionResourceRelFor(final Class<?> type) {
return super.getCollectionResourceRelFor(AbstractFoo.class);
}
@Override
public String getItemResourceRelFor(final Class<?> type) {
return super.getItemResourceRelFor(AbstractFoo.class);
}
@Override
public boolean supports(final Class<?> delimiter) {
return AbstractFoo.class.isAssignableFrom(delimiter);
}
}
编辑
- 将
@Persistent 添加到Foo.java 和Bar.java。 (将其添加到 AbstractFoo.java 不起作用)。如果没有这个注释,我在继承的类中尝试使用 JSR 303 验证注释时得到 NullPointerExceptions。
重现错误的示例代码:
public class A {
@Id public String id;
@Valid public B b;
// @JsonTypeInfo + @JsonSubTypes
public static abstract class B {
@NotNull public String s;
}
// @Persistent <- Needed!
public static class B1 extends B { }
}