在 Spring 数据的 RepositoryRestResource 中急切加载 MongoDB @DBRef
Eagerly load MongoDB @DBRef in Spring data's RepositoryRestResource
我正在尝试使用 RepositoryRestResource
和 RestTemplate
实现休息 api
除了加载@DBRef 的
外,一切都很好
考虑这个数据模型:
public class Order
{
@Id
String id;
@DBRef
Customer customer;
... other stuff
}
public class Customer
{
@Id
String id;
String name;
...
}
以及以下存储库(与客户类似)
@RepositoryRestResource(excerptProjection = OrderSummary.class)
public interface OrderRestRepository extends MongoRepositor<Order,String>{}
其余apireturns以下JSON:
{
"id" : 4,
**other stuff**,
"_links" : {
"self" : {
"href" : "http://localhost:12345/api/orders/4"
},
"customer" : {
"href" : "http://localhost:12345/api/orders/4/customer"
}
}
}
如果由 resttemplate 正确加载,将创建一个新的 Order 实例,其中 customer = null
是否可以在存储库端热切解决客户并嵌入 JSON?
在这种情况下急切解决依赖实体很可能会引发 N+1 database access problem。
我认为没有办法使用默认 Spring 数据 REST/Mongo 存储库实现来做到这一点。
这里有一些备选方案:
- 构造一个自己的自定义@RestController 方法,该方法将访问数据库并构造所需的输出
使用 Projections 填充相关集合中的字段,例如
@Projection(name = "main", types = Order.class)
public interface OrderProjection {
...
// either
@Value("#{customerRepository.findById(target.customerId)}")
Customer getCustomer();
// or
@Value("#{customerService.getById(target.customerId)}")
Customer getCustomer();
// or
CustomerProjection getCustomer();
}
@Projection(name = "main", types = Customer.class)
public interface CustomerProjection {
...
}
customerService.getById 可以使用缓存(例如使用 Spring @Cachable annotation)来减轻为每个结果集记录额外访问数据库的性能损失。
向您的数据模型添加冗余,并将 Customer 对象字段的副本存储在 creation/update 上的订单集合中。
出现这种问题,在我看来,是因为MongoDB不支持很好地连接不同的文档集合(它的"$lookup" operator与常见的[=48=相比有很大的局限性]加入)。
MongoDB docs also do not recommend 使用@DBRef 字段,除非加入托管在不同服务器上的集合:
Unless you have a compelling reason to use DBRefs, use manual references instead.
这里也有类似的question。
我正在尝试使用 RepositoryRestResource
和 RestTemplate
除了加载@DBRef 的
外,一切都很好考虑这个数据模型:
public class Order
{
@Id
String id;
@DBRef
Customer customer;
... other stuff
}
public class Customer
{
@Id
String id;
String name;
...
}
以及以下存储库(与客户类似)
@RepositoryRestResource(excerptProjection = OrderSummary.class)
public interface OrderRestRepository extends MongoRepositor<Order,String>{}
其余apireturns以下JSON:
{
"id" : 4,
**other stuff**,
"_links" : {
"self" : {
"href" : "http://localhost:12345/api/orders/4"
},
"customer" : {
"href" : "http://localhost:12345/api/orders/4/customer"
}
}
}
如果由 resttemplate 正确加载,将创建一个新的 Order 实例,其中 customer = null
是否可以在存储库端热切解决客户并嵌入 JSON?
在这种情况下急切解决依赖实体很可能会引发 N+1 database access problem。 我认为没有办法使用默认 Spring 数据 REST/Mongo 存储库实现来做到这一点。
这里有一些备选方案:
- 构造一个自己的自定义@RestController 方法,该方法将访问数据库并构造所需的输出
使用 Projections 填充相关集合中的字段,例如
@Projection(name = "main", types = Order.class) public interface OrderProjection { ... // either @Value("#{customerRepository.findById(target.customerId)}") Customer getCustomer(); // or @Value("#{customerService.getById(target.customerId)}") Customer getCustomer(); // or CustomerProjection getCustomer(); } @Projection(name = "main", types = Customer.class) public interface CustomerProjection { ... }
customerService.getById 可以使用缓存(例如使用 Spring @Cachable annotation)来减轻为每个结果集记录额外访问数据库的性能损失。
向您的数据模型添加冗余,并将 Customer 对象字段的副本存储在 creation/update 上的订单集合中。
出现这种问题,在我看来,是因为MongoDB不支持很好地连接不同的文档集合(它的"$lookup" operator与常见的[=48=相比有很大的局限性]加入)。 MongoDB docs also do not recommend 使用@DBRef 字段,除非加入托管在不同服务器上的集合:
Unless you have a compelling reason to use DBRefs, use manual references instead.
这里也有类似的question。