[Feature Request] - Let ManyToManyView support recursion
Reason
目前erp产品里有这样一种关系 Product 产品,和BOM呈一对一关系 BOM,维护Product产品的关联关系以及product的相对数量 这两个表都是基础表
create table if not exists product
(
id bigint primary key generated by default as identity,
product_type varchar(64) not null,
product_no varchar(64) not null,
name varchar(128) not null,
constraint product_no_uk unique (product_no)
);
create table if not exists bom
(
id bigint primary key generated by default as identity,
parent_product_id bigint,
component_product_id bigint not null,
nums double precision not null,
unique (parent_product_id, component_product_id),
foreign key (parent_product_id) references product (id),
foreign key (component_product_id) references product (id)
);
如果想做bom的递归查询,就需要有这样的一组结构
@Entity
@Table(name = "product")
interface Product {
val id: Long
val name: String
@ManyToMany
@JoinTable(
name = "bom",
joinColumnName = "parent_product_id",
inverseJoinColumnName = "component_product_id"
)
val children: List<Product>
}
@Entity
@Table(name = "bom")
interface BOM{
val id:Long
@ManyToOne
@Key
val parentProduct: Product?
@OneToOne
@Key
val componentProduct: Product
val nums: Double
}
但是这种情况下如果bom上也声明了@Table 就会出现报错
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.babyfish.jimmer.sql.kt.KSqlClient]: Factory method 'kotlinSqlClient' threw exception with message: Illegal entity manager, the table "BOM" is shared by both "BOM" and "MiddleTable(Product.children)"
Description
虽然目前通过创建一个view绕过去了,但是理论上一个表能同时为中间表和基础表
Existing solutions
No response
是否考虑使用 @ManyToManyView ?
是否考虑使用
@ManyToManyView?
我一直是当让ManyToManyView支持递归来理解的
是否考虑使用
@ManyToManyView?我一直是当让ManyToManyView支持递归来理解的
无论如何,不可能一表多映的。因为Jimmer是支持【触发器】的,任何binlog事件推送归来,都应该只有一种解释,而不是无穷钟解释,这个异常也防御这种问题。
我不知道题主 @zzxzz12345 的问题和我想的是否一样:如何使用 jimmer 实现以某个 Product 为根,递归查询所有子产品的物料清单?
如果 @ManyToManyView 支持递归查询子产品,那我们该如何获取这些子产品对应的 BOM 的 nums 属性呢?我感觉 Product 与 BOM 似乎只能是 “多对一” 和 “一对多”关系,无法直接为每个子产品获取对应的上下文的 BOM 中的 nums 属性。
所以,我的一个想法是,先通过 Product 和 BOM 的一对多关联查询 BOM 获取子产品和 nums 属性,然后继续通过一对多关联查询 BOM...,变成了递归查询。
让我用 Fetcher 来描述一下(伪代码):
ProductFetcher.$
.name()
.bomList(// Product 与 BOM “一对多” mappedBy = "parentProduct"
BOMFetcher.$
.nums()
// BOM 与 Product “多对一”
.componentProduct(ctx ->
ctx.recursiveRoot()
)
)
照这样分析,似乎这个问题的关键是:如何实现这种通过间接的自关联而不是直接的自关联属性定义的递归查询
如果我的理解有误,希望能得到指教🙏🏻,谢谢
是否考虑使用
@ManyToManyView?
使用@ManyToManyView看上去不会生成children*,就没法做递归查询
我不知道题主 @zzxzz12345 的问题和我想的是否一样:如何使用 jimmer 实现以某个 Product 为根,递归查询所有子产品的物料清单?
如果
@ManyToManyView支持递归查询子产品,那我们该如何获取这些子产品对应的 BOM 的nums属性呢?我感觉 Product 与 BOM 似乎只能是 “多对一” 和 “一对多”关系,无法直接为每个子产品获取对应的上下文的 BOM 中的nums属性。所以,我的一个想法是,先通过 Product 和 BOM 的一对多关联查询 BOM 获取子产品和 nums 属性,然后继续通过一对多关联查询 BOM...,变成了递归查询。
让我用 Fetcher 来描述一下(伪代码):
ProductFetcher.$ .name() .bomList(// Product 与 BOM “一对多” mappedBy = "parentProduct" BOMFetcher.$ .nums() // BOM 与 Product “多对一” .componentProduct(ctx -> ctx.recursiveRoot() ) ) 照这样分析,似乎这个问题的关键是:如何实现这种通过间接的自关联而不是直接的自关联属性定义的递归查询
如果我的理解有误,希望能得到指教🙏🏻,谢谢
不需要直接从product上获取nums属性,因为product本身还可以在声明一个one to one的结构来支持,但是目前看上只有ManyToMany和OneToMany能生成递归结构的api,ManyToManyView似乎不会触发
create view opta.product_relations as
(
select parent_product_id, component_product_id
from opta.bom);
@zzxzz12345 谢谢你的回复,目前 @ManyToManyView 确实是不支持递归的。不过,我不太理解的是 BOM 实体的关联属性 componentProduct 为什么是一对一,我的理解是:Product 可以作为 componentProduct 与多个 parentProduct 产生关联,所以 BOM 的关联属性 componentProduct 是多对一,而不是一对一。
除此之外,如果使用 @ManyToManyView 注解,其属性 deeperProp 应该为 componentProduct,但 Jimmer 不允许 deeperProp 与 prop 之间是一对一关联,这在编译时没有问题,但在运行时会报错并提示用户应该为 deeperProp 对应的关联属性声明 @ManyToOne
@zzxzz12345 谢谢你的回复,目前
@ManyToManyView确实是不支持递归的。不过,我不太理解的是 BOM 实体的关联属性componentProduct为什么是一对一,我的理解是:Product 可以作为componentProduct与多个parentProduct产生关联,所以 BOM 的关联属性componentProduct是多对一,而不是一对一。除此之外,如果使用
@ManyToManyView注解,其属性deeperProp应该为componentProduct,但 Jimmer 不允许deeperProp与prop之间是一对一关联,这在编译时没有问题,但在运行时会报错并提示用户应该为 deeperProp 对应的关联属性声明@ManyToOne
这里是临时代码写的有点问题,主要还是如果不支持递归就需要自己去写递归遍历数据了