babyfish-ct / jimmer Goto Github PK
View Code? Open in Web Editor NEWA revolutionary ORM framework for both java and kotlin.
License: Apache License 2.0
A revolutionary ORM framework for both java and kotlin.
License: Apache License 2.0
报错日志:
Caused by: java.lang.IllegalArgumentException: "io.github.AbstractEntity" is not entity
at org.babyfish.jimmer.sql.runtime.EntityManager.<init>(EntityManager.java:35)
at org.babyfish.jimmer.sql.runtime.EntityManager.combine(EntityManager.java:108)
at io.elva.server.config.JimmerConfiguration.entityManager(JimmerConfiguration.kt:27)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139)
... 48 common frames omitted
项目为多模块,因此在配置jimmer
时使用了EntityManager.combine
,combine
函数在最后进行类注册时,没有过滤掉非 @Entity
注解的类
@Bean
fun entityManager(): EntityManager {
return EntityManager.combine(
io.github.core.domain.ENTITY_MANAGER,
io.github.user.domain.ENTITY_MANAGER
)
}
// entity 基本公共类
@MappedSuperclass
interface AbstractEntity {
val createTime: LocalDateTime
val updateTime: LocalDateTime
val createBy: String?
val updateBy: String?
}
// entity
@Table(name = "sys_api_access_log")
@Entity
interface ApiAccessLog : AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long
val userId: Long?
... ...
}
As I inject the ImmultiableModule
into jackson ObjectMapper
@Bean
@Primary
public ObjectMapper objectMapper() {
return new ObjectMapper()
.registerModule(new ImmutableModule());
}
I find that customized Jackson annotation lapse and cant get the right result.
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@JacksonAnnotationsInside
@JsonSerialize(using = EnumSerializer.class)
public @interface EnumSerialize {
}
Is there any way to fix, or plan to support?
调用jimmer生成ts.zip接口时,如果是get请求,ts生成的时候,默认的是无参数的。
如:
async list(): Promise<
List<OrderInfoDto['DEFAULT']>> {
spring controller中是有参数的,比如当前页码。
请帮忙看看是我什么地方没有配置正确吗?
希望可以简化数据库 json 列的映射。
目前来说,将数据库表中 json 列映射至 entity,需要自定义 ScalarProvider
来进行列的序列化反序列化,但是每有一个这种列,都要定义一个ScalarProvider
。希望可以有一个 Json 相关通用的处理。例如 (参考 hypersistence-utils):
// 加入 @Type注解,指定该列为 JsonType,即可自动(反)序列化,无需定义 ScalarProvider
@Column(columnDefinition = "jsonb")
@Type(JsonType.class)
private ApiAccessRequestParam requestParams
Even though I know explicitly that the query will return only one result, I need to use List to receive the result set and use list.get(0) to return one result, which seems redundant.
public Role getRoleById(int id) {
RoleTable roleTable = new RoleTable();
List<Role> roles = sqlClient.createFluent()
.query(roleTable)
.where(roleTable.id().eq(id))
.select(roleTable)
.execute();
LOGGER.info("getRole: {}", roles);
return roles.get(0);
}
I suggest it can be simplified in the following way:
public Role getRoleById(int id) {
RoleTable roleTable = new RoleTable();
Optional<Role> role = sqlClient.createFluent()
.query(roleTable)
.where(roleTable.id().eq(id))
.selectOne(roleTable)
.execute();
LOGGER.info("getRole: {}", role.get());
return role.get();
}
Add an API called selectOne
to get the unique result and wrap it with Optinal.
@babyfish-ct really good staff with brilliant idea, i cannot wait to have a bit on it, when i try it within a legacy project, error comes out, it says org.babyfish.jimmer.apt.meta.MetaException: Illegal class "com.xxx.model.OrderEntity" immutable type must be interface, i know the new "entity" must be interface, but an old-fashion ORM was used, many old class entities use the same JPA annotation mechanisim, and they cannot be reformed at once, so is there any way i can ignore those old entities? so that the oldman could work together with jimmer util his retirement, thank you
比如,A实体在S1服务中,B实体在S2服务中,我在A服务中定义B类型属性时告诉它是远程数据对象,在抓取B数据时候就访问约定的远程访问接口
版本:0.7.5
详细描述:Repository的update方法在更新一个不存在的记录时,也会返回数据,同时也会走DraftInterceptor(此时isNew为false)
在数据库中有一列jsonb
类型,想当然的用ScalarProvider
写出如下转换:
但是在org.babyfish.jimmer.sql.runtime.ReaderManager#BASE_READER_MAP
中,对ScalarProvider#sqlType
的类型有如下限制:
如果ScalarProvider#sqlType
不在其中,则会抛出异常(org.babyfish.jimmer.sql.runtime.ReaderManager#scalarReader
):
希望可以提供类型限制宽松一点的数据库无关的转换方式。
另外这种方式还有一个限制,若在此处完成ScanDimensionParam -> jsonb
的转换,则所有实体中的所有ScanDimensionParam
类型的字段都会被转换成jsonb
,感觉...影响范围太大了
版本:0.7.0
详细描述:在解析类似“concat(%e, '/', %e, '/', %e) = concat(%e, '/', %e, '/', %e)”这种有超过两个占位符的表达式时,在表达式确定无误的情况下抛出异常“Too Many Expressions”
出错原因:
在org.babyfish.jimmer.sql.kt.ast.expression.impl.SqlDSL#addExpressionPlaceholder方法的第70行位置,直接对expressionPlaceholder实例变量的next属性赋值最新位置的%e,会导致head(第一个%e)的next永远是最后一个位置的%e,也因此在第三个%e时会抛出异常
可能的解决方案:
.next = it
current.next = it
jimmer: 0.6.1
jdk: 19
jimmer:
show-sql: true
@Configuration
public class JimmerConfig {
@Bean
public ImmutableModule immutableModule() {
return new ImmutableModule();
}
@Bean
public EntityManager entityManager() {
return JimmerModule.ENTITY_MANAGER;
}
@Bean(name = "sqlClient")
public JSqlClient jSqlClient(DataSource dataSource) {
return JSqlClient.newBuilder()
.setEntityManager(entityManager())
.setConnectionManager(new SpringConnectionManager(dataSource))
.setDialect(new MySqlDialect())
.build();
}
}
public List<OperationLog> findOperationLog() {
Page<OperationLog> logPage = operationLogRepository.findAll(0, 3);
List<OperationLog> logList = sqlClient.createQuery(logTable).select(logTable).limit(3, 0).execute();
return logList;
}
2022-12-30T10:32:21.621+08:00 INFO 6944 --- [nio-8080-exec-2] o.a.c.c.C.[.[localhost].[/jimmer] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-12-30T10:32:21.622+08:00 INFO 6944 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-12-30T10:32:21.622+08:00 INFO 6944 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
2022-12-30T10:32:21.675+08:00 INFO 6944 --- [nio-8080-exec-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-12-30T10:32:21.811+08:00 INFO 6944 --- [nio-8080-exec-2] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@1c46458
2022-12-30T10:32:21.813+08:00 INFO 6944 --- [nio-8080-exec-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
可以看到在日志中,不论是调用repository的接口,还是直接用sqlClient调用,都没有打印出sql。
@Configuration
public class JimmerConfig {
@Bean
public ImmutableModule immutableModule() {
return new ImmutableModule();
}
@Bean
public EntityManager entityManager() {
return JimmerModule.ENTITY_MANAGER;
}
// @Bean(name = "sqlClient")
// public JSqlClient jSqlClient(DataSource dataSource) {
// return JSqlClient.newBuilder()
// .setEntityManager(entityManager())
// .setConnectionManager(new SpringConnectionManager(dataSource))
// .setDialect(new MySqlDialect())
// .build();
// }
}
public List<OperationLog> findOperationLog() {
Page<OperationLog> logPage = operationLogRepository.findAll(0, 3);
// List<OperationLog> logList = sqlClient.createQuery(logTable).select(logTable).limit(3, 0).execute();
return logPage.getContent();
}
2022-12-30T10:34:18.376+08:00 INFO 20100 --- [nio-8080-exec-1] o.a.c.c.C.[.[localhost].[/jimmer] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-12-30T10:34:18.376+08:00 INFO 20100 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-12-30T10:34:18.376+08:00 INFO 20100 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
2022-12-30T10:34:18.426+08:00 INFO 20100 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-12-30T10:34:18.558+08:00 INFO 20100 --- [nio-8080-exec-1] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@1126732
2022-12-30T10:34:18.560+08:00 INFO 20100 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-12-30T10:34:18.565+08:00 INFO 20100 --- [nio-8080-exec-1] o.b.jimmer.sql.runtime.ExecutorForLog : jimmer> sql: select count(tb_1_.ID) from t_operation_log as tb_1_, variables: [], purpose: QUERY
2022-12-30T10:34:18.667+08:00 INFO 20100 --- [nio-8080-exec-1] o.b.jimmer.sql.runtime.ExecutorForLog : jimmer> sql: select tb_1_.ID, tb_1_.OPERATOR, tb_1_.OPERATION_ACTION, tb_1_.MODULE, tb_1_.OPERATION_IP, tb_1_.OPERATION_RESULT, tb_1_.OPERATION_ARGS, tb_1_.OPERATION_DESCRIPTION, tb_1_.OPERATION_SIZE, tb_1_.OPERATION_START_TIME, tb_1_.OPERATION_END_TIME from t_operation_log as tb_1_ limit ?, variables: [3], purpose: QUERY
可以看到此时才打印了sql
enum如何自定义显示的内容呢?
我在代码中只看到了EnumProvider相关的内容,目前应该是只能将数据库中的字段转换为 enum.name();
是否有其他的转换方法呢?
有些时候,没有办法在联表时获取到表中的逻辑主键,只能以业务主键进行联表操作,如下两种情况:
-- 两边都用多业务主键
select *
from data_security_table_result tr
join database_table_meta_info tm
on concat(tr.source, '/', tr.db_name, '/', tr.table_name)
=
concat(tm.source, '/', tm.db_name, '/', tm.table_name)
-- 一边用单业务主键,一边用多业务主键
select *
from outgoing_result "or"
join database_table_meta_info tm
on "or".obj_name
=
concat(tm.source, '/', tm.db_name, '/', tm.table_name)
希望可以对此提供支持
When using the database-validation-mode
configuration, Jimmer threw an exception DatabaseValidationException
, which indicated that there was no database table named shipments
.
However, I do have this table in my database. After removing the database-validation-mode
configuration, the project can run normally.
log表weakJoin user表,然后使用如下查询
var list = sqlClient.createQuery(logTable)
.where(wkUser.username().eq("ombs"))
.where(logTable.operationStartTime().ge(startTime))
.where(logTable.operationEndTime().le(endTime))
.where(logTable.operationAction().eq("登录").or(logTable.operationAction().eq("退出")))
.orderBy(logTable.operationStartTime().desc())
.select(logTable, user.utype())
.limit(size, page * size)
.execute();
会报错Cannot resolve the root table com.capitek.dasop.entity.User
在select中不写对象,而直接写对应字段,不会出现此问题
jimmer 版本: 0.7.9
枚举类做查询条件使用in
Cannot convert the value "1" of prop "org.github.entity.Order.orderStatus" by scalar provider "org.babyfish.jimmer.sql.runtime.EnumProviderBuilder$EnumProvider"
代码如下:
下面的代码会报错
.where(orderInfo.orderStatus().in(Arrays.asList(OrderStatusEnum.DONE, OrderStatusEnum.NOOP)))
下面的代码不会报错
.where(orderInfo.orderStatus().eq(OrderStatusEnum.DONE))
.where(orderInfo.orderStatus().ne(OrderStatusEnum.DONE))
如果使用0.7.5 不会报错
您好,我是在b站看到你的jimmer视频的,我对这个项目设计理念非常感兴趣,我希望能参入到这个开源项目里面来,首先如果想要组好一个开源项目应该有良好的编码习惯,我觉得应该先把本土化市场做好,再考虑其他国内。我看到你已经有官网了,但是代码仓库代码提交还是感觉差一点意思,一个开源项目想做大就需要更多的开发者参入进来,你一个把这个仓库设置一个组织仓库,然后把这个项目写一些文章到一些技术社区去做推广,谢谢,这是我的建议。
java.sql.Date 和 java.sql.Time 都继承自 java.util.Date,但是都不支持 toInstant 方法,67行会报错。本来想提个PR,但是我的IDEA版本是2019.3,工程都无法编译,就放弃了。就是将二者分别转成 LocalDate 和 LocalTime,再转换成 Instant。
如题,建议生成的不可变类 Impl 默认都加上 get/is 方法,反正生成的类是不对外暴露的,实际使用还是以entity为主,不会使用到其中的定义的get/is方法,但是对于绝大多数第三方类库而言会比较友好
当前的验证,如果属性是unload状态的话,是不会经过校验的,但写校验的目的就是确保该属性符合业务要求,例如
@Entity
@Table(name = "d_role")
public interface Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id();
@Nullable
String code();
@NotNull
String name();
}
该实体要求id与name不可为空,然后用于在dao层查询。
现在如果接收参数时,name没有传值,例如:
{
"id": 1
}
此时name是unload状态,则不过经过notnull校验,不会报错'name' cannot be null
。
dao层还要在验证一次isload,不仅代码臃肿,而且也不符合直觉。
是否应该由框架在校验notnull之前先完成isload判断?
Jimmer Ver: 0.7.37
Dev JDK Ver: 17
对于ID,文档中提到,对Java而言,不能是8种基本类型的装箱类型。
然而UserIdGenerator使用了泛型,只能指定装箱类型Long,导致始终无法使用long类型的ID。
@entity
public interface Entity{
@id
@GeneratedValue(generatorType = SnowflakeIdGenerator.class)
long id();
}
public class SnowflakeIdGenerator implements UserIdGenerator {
@Override
public Long generate(Class<?> entityType) {
return 1L;
}
}
Caused by: org.babyfish.jimmer.meta.ModelException: Illegal property "Entity.id", the generator type is "SnowflakeIdGenerator" generates id whose type is "java.lang.Long" but the property returns "long"
When I want to determine whether an attribute is loaded or not, the current API has only two ways
boolean pageLoaded = ImmutableObjects.isLoaded(role, "page");
boolean pageLoaded = ImmutableObjects.isLoaded(role, 12);
Both of these are not very user-friendly, and both hard-coded strings and numbers are error-prone。
I think it can be simplified to
boolean pageLoaded = ImmutableObjects.isLoaded(role, role.page());
Even more simpliy like this
boolean pageLoaded = ImmutableObjects.isLoaded(role.page());
Jimmer版本:0.7.22
伪代码如下:
public interface Dict {
String name();
}
public interface DictItem {
@ManyToOne
@Nullable
@JoinColumn(name = "dict_id")
Dict dict();
@IdView
@Nullable
Long dictId();
}
// 如果controller中有以下Fetcher,启动后会报错
DictItemFetcher.$.dictId()
// 如下写法则不会
DictItemFetcher.$.dict().dictId()
Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'typeScriptController' defined in class path resource [org/babyfish/jimmer/spring/cfg/JimmerAutoConfiguration.class]: Unsatisfied dependency expressed through method 'typeScriptController' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'metadataFactoryBean': FactoryBean threw exception on object creation; nested exception is java.lang.NullPointerException
如题,在Key和OneToOne同时作用在一个注解上时,最终生成的SQL语句中的列名是把属性名称全大写下加划线,是一个不存在的列
会导致如下报错:
Cannot execute SQL statement: select tb_1_.ID, tb_1_.CATALOG_ID, tb_1_.GROUP from SCAN_DIMENSION_CATALOG_GROUP as tb_1_ where tb_1_.CATALOG_ID = ? and tb_1_.GROUP = ?, variables: [14, 9]
2023-02-25T12:47:59.864+08:00 WARN 27344 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: @Configuration class 'SqlClientConfig' contains overloaded @Bean methods with name 'caches'. Use unique method names for separate bean definitions (with individual conditions etc) or switch '@Configuration.enforceUniqueMethods' to 'false'.
Offending resource: class path resource [org/babyfish/jimmer/spring/cfg/SqlClientConfig.class]
2023-02-25T12:47:59.935+08:00 INFO 27344 --- [ main] .s.b.a.l.ConditionEvaluationReportLogger :
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-02-25T12:47:59.952+08:00 ERROR 27344 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: @Configuration class 'SqlClientConfig' contains overloaded @Bean methods with name 'caches'. Use unique method names for separate bean definitions (with individual conditions etc) or switch '@Configuration.enforceUniqueMethods' to 'false'.
Offending resource: class path resource [org/babyfish/jimmer/spring/cfg/SqlClientConfig.class]
在数据量比较大的情况下,单纯的分页查询效率不如先用子查询查出主键id 再用主键id关联显示数据的效率高,希望可以支持子查询的分页查询
目前使用postgresql,表中有一个Json字段,如何映射到@Entity
类中呢?
文档里没看到相关内容,直接用类接收就出现类型转换错误。
Failed the convert the result value at column $6, the expected type is 'xxxx', but the actual type is 'org.postgresql.util.PGobject'
在BetweenPredicate中的renderTo方法里面,builder.sql(if (negative) " not between " else "between"),由于between前后没有空格导致SQL语句拼接错误
Pagination Query are too cumbersome now.
TypedRootQuery<Long> countQuery = query
.reselect((q, t) ->
q.select(t.count())
)
.withoutSortingAndPaging();
int rowCount = countQuery.execute().get(0).intValue();
List<Book> books = query
.limit(rowCount / 3, rowCount / 3)
.execute();
I wish it could be simplified to an API to get the count directly, like this
long count = query.getCount();
Because I think the specific implementation details should be understood as source code and should not appear in everyday use. It is much easier and faster to use only one API to get the results.
提这个问题的时候我似乎意识到这与ksp可能有冲突,但我还是很好奇有没有这种可能性?
我希望将表关系的定义持久化是因为我希望能够在运行时动态配置他们,这样我就有可能实现通用数据访问层了。
进一步地,通过某种手段将查询操作符映射为字符串表达式,那么只要建个表就可以应对大多数的查询场景了。
版本: 0.7.0
JRepository或KJRepository中没有提供findAll(Predicate predicate)
和findOne(Predicate predicate)
这样的方法
类似QueryDsl中的QuerydslPredicateExecutor
:
public interface QuerydslPredicateExecutor<T> {
Optional<T> findOne(Predicate predicate);
Iterable<T> findAll(Predicate predicate);
}
是否可以考虑实现这样的方法呢?
我尝试实现这样的方法时, 碰到了一个问题
SqlClient没有createQuery(Class<?> entityClass)
这样能够基于实体类型创建查询的方法, 只有通过Table<E>
创建查询的方法, 因此必须通过repository提供Table
对象才可能实现.
例如:
public interface BaseJimmerRepository<E, ID> extends JRepository<E, ID> {
<T extends TableProxy<E>> T table();
default List<E> findAll(Predicate predicate) {
return sql().createQuery(table()).where(predicate).select(table()).execute();
}
}
实体的Repository:
public interface DeviceJimmerRepository extends BaseJimmerRepository<Device,Long> {
@Override default DeviceTable table() {
return DeviceTable.$;
}
}
Repository中能内置实现这种方法吗, 亦或者提供方便检索实体对应的Table
的方法呢?
------------------------------------编辑
我找到了JRepositoryImpl中的一个方法org.babyfish.jimmer.spring.repository.support.JRepositoryImpl#createQuery
private ConfigurableRootQuery<?, E> createQuery(Fetcher<E> fetcher, TypedProp.Scalar<?, ?>[] sortedProps) {
MutableRootQueryImpl<Table<E>> query =
new MutableRootQueryImpl<>(sqlClient, immutableType, ExecutionPurpose.QUERY, false);
Table<E> table = query.getTable();
for (TypedProp.Scalar<?, ?> sortedProp : sortedProps) {
if (!sortedProp.unwrap().getDeclaringType().isAssignableFrom(immutableType)) {
throw new IllegalArgumentException(
"The sorted field \"" +
sortedProp +
"\" does not belong to the type \"" +
immutableType +
"\" or its super types"
);
}
PropExpression<?> expr = table.get(sortedProp.unwrap().getName());
Order astOrder;
if (sortedProp.isDesc()) {
astOrder = expr.desc();
} else {
astOrder = expr.asc();
}
if (sortedProp.isNullsFirst()) {
astOrder = astOrder.nullsFirst();
}
if (sortedProp.isNullsLast()) {
astOrder = astOrder.nullsLast();
}
query.orderBy(astOrder);
}
query.freeze();
return query.select(fetcher != null ? table.fetch(fetcher) : table);
}
也许我知道该怎么自己实现了
----------------------------编辑
出问题了
jdk版本: 17
jimmer版本: 0.7.0
异常栈:
java.lang.IllegalArgumentException: Cannot resolve the root table xxx.xxx.xxx.Device
at org.babyfish.jimmer.sql.ast.impl.AstContext.resolveRootTable(AstContext.java:85) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.table.spi.AbstractTypedTable.__resolve(AbstractTypedTable.java:334) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.table.TableProxies.resolve(TableProxies.java:142) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.PropExpressionImpl.accept(PropExpressionImpl.java:109) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.ComparisonPredicate.accept(ComparisonPredicate.java:26) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.query.AbstractMutableQueryImpl.accept(AbstractMutableQueryImpl.java:191) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.query.AbstractConfigurableTypedQueryImpl.accept(AbstractConfigurableTypedQueryImpl.java:53) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.query.ConfigurableRootQueryImpl.accept(ConfigurableRootQueryImpl.java:21) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.query.ConfigurableRootQueryImpl.preExecute(ConfigurableRootQueryImpl.java:201) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.query.ConfigurableRootQueryImpl.executeImpl(ConfigurableRootQueryImpl.java:155) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.spring.repository.SpringConnectionManager.execute(SpringConnectionManager.java:22) ~[jimmer-spring-boot-starter-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.query.ConfigurableRootQueryImpl.execute(ConfigurableRootQueryImpl.java:135) ~[jimmer-sql-0.7.0.jar:na]
at org.babyfish.jimmer.sql.ast.impl.query.ConfigurableRootQueryImpl.execute(ConfigurableRootQueryImpl.java:21) ~[jimmer-sql-0.7.0.jar:na]
at xxx.xxx.xxx.xxx..xxx.BaseJimmerRepository.findAll(BaseJimmerRepository.java:69) ~[classes/:na]
其中BaseJimmerRepository
中的代码如下:
@NoRepositoryBean
public interface BaseJimmerRepository<E>
extends JRepository<E, Long> {
private ConfigurableRootQuery<?, E> createQuery(
Predicate predicate, Fetcher<E> fetcher, TypedProp.Scalar<?, ?>[] sortedProps) {
var immutableType = type();
MutableRootQueryImpl<Table<E>> query =
new MutableRootQueryImpl<>(sql(), immutableType, ExecutionPurpose.QUERY, false);
Table<E> table = query.getTable();
for (TypedProp.Scalar<?, ?> sortedProp : sortedProps) {
if (!sortedProp.unwrap().getDeclaringType().isAssignableFrom(immutableType)) {
throw new IllegalArgumentException(
"The sorted field \""
+ sortedProp
+ "\" does not belong to the type \""
+ immutableType
+ "\" or its super types");
}
PropExpression<?> expr = table.get(sortedProp.unwrap().getName());
Order astOrder;
if (sortedProp.isDesc()) {
astOrder = expr.desc();
} else {
astOrder = expr.asc();
}
if (sortedProp.isNullsFirst()) {
astOrder = astOrder.nullsFirst();
}
if (sortedProp.isNullsLast()) {
astOrder = astOrder.nullsLast();
}
query.orderBy(astOrder);
}
var tableMutableRootQuery = query.where(predicate);
query.freeze();
return tableMutableRootQuery.select(fetcher != null ? table.fetch(fetcher) : table);
}
default List<E> findAll(Predicate predicate) {
return createQuery(predicate).execute(); // 调用execute报错
}
controller调用的代码
@GetMapping("test")
public List<xxx.xxx.xxx.xxx.Device> test() {
return deviceJimmerRepository.findAll(DeviceTable.$.mac().eq("0011AABBCC00"));
}
看起来是MutableRootQueryImpl
的getTable
返回的Table
不能用来组成条件.
所以还是回到最开始的问题: 是否考虑由Repository提供通过Predicate的查询, 或可以通过实体类检索Table对象的方法, 如果不考虑的话, 我就只能采用实体的Repository提供table的方式了.
RT.
查看源码JRepositoryImpl.deleteAll()实现调用的是
@Override
public void deleteAll() {
Mutations
.createUpdate(sqlClient, immutableType, (d, t) -> {})
.execute();
}
是否应该调用createDelete? 手误?还是我的理解错误?
This seems a bit cumbersome
addScalarProvider(
ScalarProvider.enumProviderByString(
Gender::class.java
) {
it
.map(Gender.MALE, "M")
.map(Gender.FEMALE, "F")
}
)
场景描述:引入jimmer-apt后,@requestbody pojo 不能接收到入参。删除jimmer dependency后可以正常解析。
当前版本:0.6.15
依赖:jimmer-spring-boot-starter jimmer-apt。
尝试降级至0.6.10也存在这个问题。其它版本未尝试
val medias = mediaDtos.map { media ->
new(Media::class).by {
MediaType.valueOf(media.type)?.let {
this.type = it
}
media.url?.let {
this.url = it
}
this.order = media.order ?: 0
}
}
val result = sqlClient
.entities
.batchSave(medias) {
setMode(SaveMode.INSERT_ONLY)
}
result.simpleResults.map {
it.modifiedEntity.id
}
import com.wonderkids.api.core.enums.MediaType
import org.babyfish.jimmer.sql.*
@Entity
@Table(name = "WK_MEDIA")
interface Media {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long
val type: MediaType
val url: String
@Column(name = "`ORDER`")
val order: Int
}
版本:0.6.1
语言:Kotlin
Kotlin编译器版本:1.7.10
Gradle依赖:
implementation("org.babyfish.jimmer:jimmer-spring-boot-starter:0.6.1")
ksp("org.babyfish.jimmer:jimmer-ksp:0.6.1")
ksp生成代码ReimbursementDraft.kt
:
ksp报错为:
e: (路径省略)\entity\ReimbursementDraft.kt: (621, 25): Expecting an element
如图,大概是第621行的!==
被错误地换行导致其出现在了行首,导致编译错误,我个人手动将!==
前的换行删掉便不再编译报错(我个人并未测试运行时是否会出现异常)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.