Digest for jooq-user@googlegroups.com - 4 updates in 2 topics

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Digest for jooq-user@googlegroups.com - 4 updates in 2 topics

http://groups.google.com/group/jooq-user/topics mailing list
Lukas Eder <[hidden email]>: Sep 03 04:14PM +0200

Hi Marek,
 
Thank you very much for your quick feedback.
 
Indeed, being able to parse unqualified column references will prove tricky
as we will have to defer some lookups until we have all the table
expressions available. There are many edge cases, e.g. when using lateral
derived tables, where our current single pass recursive descent parser
might not be good enough. This will be fixed through
https://github.com/jOOQ/jOOQ/issues/9061, hopefully in 3.13.
 
Regarding that last parse call, what else would you suggest? I mean, the
SQL you passed to DSLContext::meta has a syntax error... There's an excess
",". Or do you mean the reflection warning? We're trying to address that as
soon as possible.
 
Thanks,
Lukas
 
Matthias Kurz <[hidden email]>: Sep 03 09:07AM +0200

Thanks for you helpful answers Lukas!
Looking forward to your next blog posts and also the roadmap, which will be
very interesting ;)
 
Kind regards,
Matthias
 
David Karlsen <[hidden email]>: Sep 03 12:44AM -0700

I looked closer into the code and found out where the issue is.
 
I have a class:
 
public class InitialValueOnCreateListener {
 
private InitialValueOnCreateListener() {}
 
public static <T> RecordListener create(
String columName, Class<? super T> type, Supplier<T> initialValue) {
return new DefaultRecordListener() {
@Override
public void insertStart(RecordContext ctx) {
Arrays.stream(ctx.record().fields())
.filter(f -> shouldAssign(f, ctx, columName, type))
.forEach(o -> ctx.record().setValue(o.cast(type), initialValue.get()));
}
};
}
 
private static boolean shouldAssign(
Field<?> f, RecordContext recordContext, String columnName, Class type) {
return f.getValue(recordContext.record()) == null
&& f.getName().equalsIgnoreCase(columnName)
&& f.getType().isAssignableFrom(type);
}
}
 
 
and in my config:
 
@Bean
public RecordListenerProvider[] recordListenerProviders() {
return DefaultRecordListenerProvider.providers(
// InitialValueOnCreateListener.create("VERSION", BigInteger.class, () -> BigInteger.ZERO),
InitialValueOnCreateListener.create("CREATED_DT", LocalDateTime.class, LocalDateTime::now));
}
 
 
and get the stack-trace:
 
 
java.lang.IllegalArgumentException: Field
(cast("APPDATA"."T_ADDRESS"."CREATED_DT" as timestamp)) is not contained in
Row ("APPDATA"."T_ADDRESS"."ID", "APPDATA"."T_ADDRESS"."VERSION",
"APPDATA"."T_ADDRESS"."ADDRESSLINE1", "APPDATA"."T_ADDRESS"."ADDRESSLINE2",
"APPDATA"."T_ADDRESS"."ADDRESSTYPE", "APPDATA"."T_ADDRESS"."CITY",
"APPDATA"."T_ADDRESS"."ISOCOUNTRYCODE", "APPDATA"."T_ADDRESS"."ZIPCODE",
"APPDATA"."T_ADDRESS"."CUSTOMER_ID", "APPDATA"."T_ADDRESS"."CREATED_DT",
"APPDATA"."T_ADDRESS"."UPDATED_DT")
 
at org.jooq.impl.Tools.indexOrFail(Tools.java:1814)
at org.jooq.impl.AbstractRecord.set(AbstractRecord.java:338)
at org.jooq.impl.AbstractRecord.setValue(AbstractRecord.java:1312)
at
com.edb.fs.tac.jfr.srv.dao.InitialValueOnCreateListener$1.lambda$insertStart$1(InitialValueOnCreateListener.java:25)
at
java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at
java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at
java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at
java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at
java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at
java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at
java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at
java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at
java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at
com.edb.fs.tac.jfr.srv.dao.InitialValueOnCreateListener$1.insertStart(InitialValueOnCreateListener.java:25)
at org.jooq.impl.RecordDelegate.operate(RecordDelegate.java:115)
at org.jooq.impl.TableRecordImpl.storeInsert(TableRecordImpl.java:173)
at org.jooq.impl.TableRecordImpl.insert(TableRecordImpl.java:161)
at org.jooq.impl.TableRecordImpl.insert(TableRecordImpl.java:156)
at org.jooq.impl.BatchCRUD.executeAction(BatchCRUD.java:210)
at org.jooq.impl.BatchCRUD.executePrepared(BatchCRUD.java:121)
at org.jooq.impl.BatchCRUD.execute(BatchCRUD.java:96)
at
com.edb.fs.tac.jfr.srv.dao.customer.CustomerDaoJooqImpl.createCustomer(CustomerDaoJooqImpl.kt:88)
at
com.edb.fs.tac.jfr.srv.dao.customer.CustomerDaoJooqImpl$$FastClassBySpringCGLIB$$f13bda37.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at
org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:119)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at
com.edb.fs.tac.jfr.srv.dao.customer.CustomerDaoJooqImpl$$EnhancerBySpringCGLIB$$a63bc9e5.createCustomer(<generated>)
at
com.edb.fs.tac.jfr.srv.service.customer.CustomerServiceImpl.createCustomer(CustomerServiceImpl.kt:32)
at
com.edb.fs.tac.jfr.srv.service.customer.CustomerServiceImpl$$FastClassBySpringCGLIB$$6b3d1210.invoke(<generate
 
 
which is a regression from 3.11.x
 
fredag 30. august 2019 13.38.03 UTC+2 skrev Lukas Eder følgende:
Lukas Eder <[hidden email]>: Sep 03 09:51AM +0200

Hi David,
 
Thanks for your additional details. I'm not sure if this is really a
regression, I'm surprised it worked before. The problem is your cast here:
 
public void insertStart(RecordContext ctx) {
Arrays.stream(ctx.record().fields())
.filter(f -> shouldAssign(f, ctx, columName, type))
.forEach(o -> ctx.record().setValue(o.cast(type),
initialValue.get()));
}
 
You're probably casting things to get around type safety issues. But a
Field.cast() call creates a completely different Field expression, which
has nothing to do with the original field. In particular, your Record does
not actually contain that field expression, so throwing an exception is a
sensible thing to do here, because your intent might have been to
distinguish between two distinct expressions o and o.cast(type) (in case
both were inside the record).
 
Regrettably, Java does not allow for using local generic types, so you
might need to resort to unsafe casting (in Java, not using jOOQ API!) or an
auxiliary method, or you could use Field::coerce, whose purpose is to
change a field's type without any effect on the underlying SQL.
 
I recommend using casting, though:
 
public void insertStart(RecordContext ctx) {
Arrays.stream(ctx.record().fields())
.filter(f -> shouldAssign(f, ctx, columName, type))
.forEach(o -> ctx.record().setValue((Field<T>) o, (T)
initialValue.get()));
}
 
I hope this helps,
Lukas
 
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to [hidden email].