gpt4 book ai didi

具有抽象类/继承的 Spring Data Rest Repository

转载 作者:行者123 更新时间:2023-12-02 07:06:53 28 4
gpt4 key购买 nike

我无法让 Spring Data Rest 与类继承一起工作。

我想要一个 JSON 端点来处理我所有的具体类。

repo 协议(protocol):

public interface AbstractFooRepo extends KeyValueRepository<AbstractFoo, String> {}

抽象类:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = MyFoo.class, name = "MY_FOO")
})
public abstract class AbstractFoo {
@Id public String id;
public String type;
}

具体类:

public class MyFoo extends AbstractFoo { }

现在,当使用 {"type":"MY_FOO"} 调用 POST/abstractFoos 时,它告诉我: java.lang.IllegalArgumentException: PersistentEntity 不得为空!

这似乎会发生,因为 Spring 不知道 MyFoo

是否有某种方法可以告诉 Spring Data REST 有关 MyFoo 的信息,而无需为其创建存储库和 REST 端点?

(我正在使用 Spring Boot 1.5.1 和 Spring Data REST 2.6.0)

编辑:

应用程序.java:

@SpringBootApplication
@EnableMapRepositories
public class Application {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

最佳答案

我正在使用 Spring Boot 1.5.1 和 Spring Data Release Ingalls

KeyValueRepository 不适用于继承。它使用每个保存对象的类名来查找相应的键值存储。例如。 save(new Foo()) 会将保存的对象放入 Foo 集合中。并且 abstractFoosRepo.findAll() 将在 AbstractFoo 集合中查找,并且不会找到任何 Foo 对象。

这是使用 MongoRepository 的工作代码:

应用程序.java

默认 Spring Boot 应用程序启动器。

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

AbstractFoo.java

  • 我已经测试了 include = JsonTypeInfo.As.EXISTING_PROPERTYinclude = 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);
}
}
<小时/>

编辑

  • Foo.javaBar.java 添加了 @Persistent。 (将其添加到 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 { }
}

关于具有抽象类/继承的 Spring Data Rest Repository,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42121506/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com