DB2 not accepting UUID - spring-data-jpa

I am using UUID datatype for generating alpha numeric primary key. Following is the code:
public class Example {
private UUID id;
#Id
#Column(name = "ID", nullable = false, length = 36)
#GeneratedValue(generator = "system-uuid")
#GenericGenerator(name = "system-uuid", strategy = "uuid2")
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
}
The Java code is generating the uuid something like - c70e22b4-d2a8-11ea-87d0-0242ac130003.
But on saving the values in a DB2 table, in UUID column(which is of VARCHAR(25) type in DB2), I am getting values as in table as:
<failed to load>
com.ibm.db2.jcc.am.SqlException: [jcc][t4][1065][12306][4.23.42] Caught java.io.CharConversionException. See attached Throwable for details. ERRORCODE=-4220, SQLSTATE=null
at com.ibm.db2.jcc.am.ld.a(ld.java:794)
at com.ibm.db2.jcc.am.ld.a(ld.java:66)
at com.ibm.db2.jcc.am.ld.a(ld.java:125)
at com.ibm.db2.jcc.am.mc.a(mc.java:2963)
at com.ibm.db2.jcc.am.mc.p(mc.java:575)
at com.ibm.db2.jcc.am.mc.P(mc.java:1656)
at com.ibm.db2.jcc.am.ResultSet.getStringX(ResultSet.java:1223)
at com.ibm.db2.jcc.am.ResultSet.getString(ResultSet.java:1192)
at com.intellij.database.remote.jdbc.impl.RemoteResultSetImpl.tryGetObject(RemoteResultSetImpl.java:1289)
at com.intellij.database.remote.jdbc.impl.RemoteResultSetImpl.getObject(RemoteResultSetImpl.java:1272)
at com.intellij.database.remote.jdbc.impl.RemoteResultSetImpl.getCurrentRow(RemoteResultSetImpl.java:1249)
at com.intellij.database.remote.jdbc.impl.RemoteResultSetImpl.getObjects(RemoteResultSetImpl.java:1229)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
at com.ibm.db2.jcc.am.r.a(r.java:52)
at com.ibm.db2.jcc.am.mc.a(mc.java:2952)
... 25 more
Looks like I can not map UUID to Varchar, but not able to find the alternative.
Any help would be appreciated.

Not sure where you got a length of 25 from....
c70e22b4-d2a8-11ea-87d0-0242ac130003 is 36 characters...
if you want to store the binary value, you only need 16 bytes, but they must for CHAR(16) FOR BIT DATA

You can convert text UUID stings in Db2 to binary with the [VARCHAR_BIT_FORMAT][1] function
CREATE TABLE UUID(U BINARY(16) NOT NULL PRIMARY KEY)
;
INSERT INTO UUID
VALUES VARCHAR_BIT_FORMAT(
'c70e22b4-d2a8-11ea-87d0-0242ac130003'
, 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
)

Related

Problem to add new User Spring-Boot / Postman

Can you help me? I have a problem adding a new client to my database.
I have three classes: User, Role, Center
my user class contains:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String login;
private String password;
private String nom;
private String prenom;
private String telephone;
private String email;
private long idCCMS;
private String matricule;
#ManyToOne
#JoinColumn(name = "Code_Role")
private Role role;
#ManyToOne
#JoinColumn(name = "Code_Centre")
private Centre centre;
my method:
#PostMapping(value = "/add")
public Utilisateur save(#RequestBody Utilisateur user) {
return userRepo.save(user);
}
How I can affect the addition of a new user by assigning him a role and a center.
I tried this solution with postman :
{
"login": "med",
"password": "123456789",
"nom": "AOUIDIDI",
"prenom": "MOHAMED WALID",
"telephone": "(+222) 22-222-222",
"email": "aaa#aaa.com",
"idccms": 08318915,
"matricule": "431908",
"code_role":"3",
"code_centre":"3"
}
I got this result:
"timestamp": "2020-02-06T13:15:41.496+0000",
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Invalid numeric value: Leading zeroes not allowed; nested exception is com.fasterxml.jackson.core.JsonParseException: Invalid numeric value: Leading zeroes not allowed\n at [Source: (PushbackInputStream); line: 8, column: 16]",
"trace": "org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Invalid numeric value: Leading zeroes not allowed; nested exception is com.fasterxml.jackson.core.JsonParseException: Invalid numeric value: Leading zeroes not allowed\n at [Source: (PushbackInputStream); line: 8, column: 16]\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:245)\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:227)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:205)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:158)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:131)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:660)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:741)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.lang.Thread.run(Unknown Source)\r\nCaused by: com.fasterxml.jackson.core.JsonParseException: Invalid numeric value: Leading zeroes not allowed\n at [Source: (PushbackInputStream); line: 8, column: 16]\r\n\tat com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1840)\r\n\tat com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:712)\r\n\tat com.fasterxml.jackson.core.base.ParserMinimalBase.reportInvalidNumber(ParserMinimalBase.java:551)\r\n\tat com.fasterxml.jackson.core.json.UTF8StreamJsonParser._verifyNoLeadingZeroes(UTF8StreamJsonParser.java:1519)\r\n\tat com.fasterxml.jackson.core.json.UTF8StreamJsonParser._parsePosNumber(UTF8StreamJsonParser.java:1371)\r\n\tat com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextFieldName(UTF8StreamJsonParser.java:1055)\r\n\tat com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:376)\r\n\tat com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)\r\n\tat com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)\r\n\tat com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3258)\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:239)\r\n\t... 51 more\r\n",
"path": "/utilisateurs/add"
}
can you help me solve this problem please ?
As your response says:
...line: 8, column: 16 ... Invalid numeric value: Leading zeroes not allowed
"idccms": 08318915 can not be parsed to private long idCCMS;
Either get rid of the 0 in the beginning or make idCCMS a type of String and everything will be just fine.

Store Kotlin inline class to MongoDB with Spring Data

I'm trying to store a Kotlin's (v1.3.61) inline class to a MongoDB using Spring Data MongoDB (2.2.3-RELEASE), with no luck so far. This is the set up:
inline class UserId(#NotBlank val id: String)
and
#Document(collection = "data")
class Data(
#Field("uid")
val userId: UserId
)
Spring throws the following exception when creating its beans:
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1 at
org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers.buildPreferredConstructor(PreferredConstructorDiscoverer.java:221)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers.access$200(PreferredConstructorDiscoverer.java:89)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers$2.lambda$discover$0(PreferredConstructorDiscoverer.java:161)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
~[na:1.8.0_171] at
java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
~[na:1.8.0_171] at
java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
~[na:1.8.0_171] at
java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
~[na:1.8.0_171] at
java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
~[na:1.8.0_171] at
java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
~[na:1.8.0_171] at
java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
~[na:1.8.0_171] at
java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
~[na:1.8.0_171] at
java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
~[na:1.8.0_171] at
org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers$2.discover(PreferredConstructorDiscoverer.java:164)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mapping.model.PreferredConstructorDiscoverer.discover(PreferredConstructorDiscoverer.java:77)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mapping.model.BasicPersistentEntity.(BasicPersistentEntity.java:105)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity.(BasicMongoPersistentEntity.java:74)
~[spring-data-mongodb-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:91)
~[spring-data-mongodb-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:39)
~[spring-data-mongodb-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:357)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:323)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_171] at
org.springframework.data.mapping.context.AbstractMappingContext.initialize(AbstractMappingContext.java:452)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.data.mapping.context.AbstractMappingContext.afterPropertiesSet(AbstractMappingContext.java:444)
~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855)
~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792)
~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE] ... 151 common frames
omitted
The stacktrace is quite obscure, but the exception occurs in the PreferredConstructorDiscoverer and the userId is part of the constructor, so the issue might be located there.
Next thing was checking the byte code of the Data class:
// ================net/test/Data.class
================= // class version 50.0 (50) // access flags 0x31
public final class net/test/Data {
#Lorg/springframework/data/mongodb/core/mapping/Document;(collection="data")
// access flags 0x12 private final Ljava/lang/String; userId #Lorg/springframework/data/mongodb/core/mapping/Field;(value="uid") #Lorg/jetbrains/annotations/NotNull;() // invisible
// access flags 0x11 public final getUserId()Ljava/lang/String; #Lorg/jetbrains/annotations/NotNull;() // invisible L0
LINENUMBER 10 L0
ALOAD 0
GETFIELD net/test/Data.userId : Ljava/lang/String;
ARETURN L1
LOCALVARIABLE this Lnet/test/Data; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x2 private <init>(Ljava/lang/String;)V L0
LINENUMBER 7 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
ALOAD 0
ALOAD 1
PUTFIELD net/test/Data.userId : Ljava/lang/String;
RETURN L1
LOCALVARIABLE this Lnet/test/Data; L0 L1 0
LOCALVARIABLE userId Ljava/lang/String; L0 L1 1
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x1001 public synthetic <init>(Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
// annotable parameter count: 2 (visible)
// annotable parameter count: 2 (invisible) L0
LINENUMBER 7 L0
ALOAD 0
ALOAD 1
INVOKESPECIAL net/test/Data.<init> (Ljava/lang/String;)V
RETURN L1
LOCALVARIABLE this Lnet/test/Data; L0 L1 0
LOCALVARIABLE userId Ljava/lang/String; L0 L1 1
LOCALVARIABLE $constructor_marker Lkotlin/jvm/internal/DefaultConstructorMarker; L0 L1 2
MAXSTACK = 2
MAXLOCALS = 3
#Lkotlin/Metadata;(mv={1, 1, 16}, bv={1, 0, 3}, k=1, d1={"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\u0008\u0005\u0008\u0007\u0018\u00002\u00020\u0001B\u0010\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0004R\u001b\u0010\u0002\u001a\u00020\u00038\u0006X\u0087\u0004\u00f8\u0001\u0000\u00a2\u0006\n\n\u0002\u0010\u0007\u001a\u0004\u0008\u0005\u0010\u0006\u0082\u0002\u0004\n\u0002\u0008\u0019\u00a8\u0006\u0008"}, d2={"Lnet/test/Data;", "", "userId", "Lnet/test/UserId;", "(Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V", "getUserId", "()Ljava/lang/String;", "Ljava/lang/String;", "core"}) // compiled from: Data.kt }
// ================META-INF/core.kotlin_module =================
and this is the relevant line 221 of the PreferredConstructorDiscoverer from the Spring source:
String name = parameterNames == null ? null : parameterNames[i];
I'm a total noob in understand byte code, but one or the other might see the issue right away.
Something else I've tried was implementing two custom converters of type org.springframework.core.convert.converter.Converter<UserId,String> and vice versa. However, the bean instantiation takes place before any conversion can occur, so this seems to be irrelevant.
I'm aware that inline classes are still experimental in Kotlin 1.3, but maybe the actual issue lies somewhere else. Does anybody have an idea?
By the way, when changing the type from UserId to String everything works fine.
I'm using a workaround for this, by introducing a private field.
inline class UserId(#NotBlank val id: String = UUID.randomUUID().toString())
#Document(collection = "data")
data class Data(
#Transient val userId: UserId = UserId()
) {
#Id private val idData = userId.id
}
But with this approach you should switch from extending CRUD-Interfaces to implement the basic operations by yourself (otherwise the ID-class makes no sense):
// introduce some extension functions for easier use with mongo-template
suspend inline fun <T> ReactiveMongoTemplate.saveAndAwait(entity: T) : T =
save(entity).awaitSingle()
suspend inline fun <reified T> ReactiveMongoTemplate.findById(id: Any) : T =
findById(id, T::class.java).awaitSingle()
#ExperimentalCoroutinesApi
#Repository
internal class DataRepository(
private val template: ReactiveMongoTemplate
) {
suspend fun save(order: Order) : Order = template.saveAndAwait(order)
suspend fun findById(orderId: OrderId): Order = template.findById(orderId.id)
}
If its worth the overhead?
Pro:
Typed Ids
in Mongo the id-column is still a primitive
Cons:
Repositories get more complex
If DATACMNS-1517 is fixed sometime in the future, adaption should be relatively easy (mostly the implementation of repositories is removed in favour to extended interfaces).
Have you seen Spring data JPA throwing java.lang.ArrayIndexOutOfBoundsException: X [Kotlin]? Looks like there is no good workaround for this issue. Here is the issue for Spring Data https://jira.spring.io/browse/DATACMNS-1517.

primary key ID gives me repeated " 0 " value with android app

I try to make contactsApp with android , when I debug it the primary key repeat its value which is zero
AND HERE IS THE SQLiteOpenHelper class :
// get all Contacts
public List<Contact> getAllContact(){
SQLiteDatabase db = this.getReadableDatabase();
List<Contact> contactList = new ArrayList<>();
String selectAll = "SELECT * FROM " + Util.TABLE_NAME;
Cursor cursor = db.rawQuery(selectAll , null);
if (cursor.moveToFirst()){
do {
Contact contact = new Contact();
// HERE is where the error come...
try{
if (cursor.getString(0) != null)
contact.setId(Integer.parseInt(cursor.getString(0)));
}catch (Exception e){e.printStackTrace();}
contact.setName(cursor.getString(1) );
contact.setPhoneNumber(cursor.getString(2));
contactList.add(contact);
}while (cursor.moveToNext());
}
return contactList;
}
at first the error was NonNullException at this line
contact.setId(Integer.parseInt(cursor.getString(0)));
so I surround it with try catch then the app debug correctly but still gives wrong value for the INTEGER PRIMARY KEY id
the final result should be like
ID: 1, Name 1 , 111111111
ID: 2, Name 2 , 22222222
ID: 3, Name 3 , 33333333
ID: 4, Name 4 , 444444444
But I get this result..
ID: 0, Name 1 , 111111111
ID: 0, Name 2 , 22222222
ID: 0, Name 3 , 33333333
ID: 0, Name 4 , 444444444
after some searches I did not find any solution for that!
So what should I do to fix it ??
Thanks in advance!
EDIT
The stack-trace :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.muhamad_galal.databaseintro, PID: 3947
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.muhamad_galal.databaseintro/com.example.muhamad_galal.databaseintro.MainActivity}: java.lang.NumberFormatException: Invalid int: "null"
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NumberFormatException: Invalid int: "null"
at java.lang.Integer.invalidInt(Integer.java:138)
at java.lang.Integer.parseInt(Integer.java:358)
at java.lang.Integer.parseInt(Integer.java:334)
at Data.DataBaseHandler$override.getAllContact(DataBaseHandler.java:141)
at Data.DataBaseHandler$override.access$dispatch(DataBaseHandler.java)
at Data.DataBaseHandler.getAllContact(DataBaseHandler.java)
at com.example.muhamad_galal.databaseintro.MainActivity$override.onCreate(MainActivity.java:29)
at com.example.muhamad_galal.databaseintro.MainActivity$override.access$dispatch(MainActivity.java)
at com.example.muhamad_galal.databaseintro.MainActivity.onCreate(MainActivity.java)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 
at android.app.ActivityThread.-wrap15(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
What the message is saying is that you've passed a null to the Integer's parseInt method. as per :-
Caused by: java.lang.NumberFormatException: Invalid int: "null"
Thus it appears that the first column of the table has nulls.
At a guess you have not defined the column to be an alias of rowid and thus the column hasn't been given a unique integer value.
To be an alias of rowid it must be defined as INTEGER PRIMARY KEY or INTEGER PRIMARY KEY AUTOINCREMENT (the latter is not recommended).
If you changed :-
public List<Contact> getAllContact(){
SQLiteDatabase db = this.getReadableDatabase();
List<Contact> contactList = new ArrayList<>();
String selectAll = "SELECT * FROM " + Util.TABLE_NAME;
Cursor cursor = db.rawQuery(selectAll , null);
if (cursor.moveToFirst()){
do {
Contact contact = new Contact();
// HERE is where the error come...
try{
if (cursor.getString(0) != null)
contact.setId(Integer.parseInt(cursor.getString(0)));
}catch (Exception e){e.printStackTrace();}
contact.setName(cursor.getString(1) );
contact.setPhoneNumber(cursor.getString(2));
contactList.add(contact);
}while (cursor.moveToNext());
}
return contactList;
}
to (see the comments at the end of lines that start with //<<<<) :-
public List<Contact> getAllContact(){
SQLiteDatabase db = this.getReadableDatabase();
List<Contact> contactList = new ArrayList<>();
String selectAll = "SELECT rowid,* FROM " + Util.TABLE_NAME; //<<<< CHANGED
Cursor cursor = db.rawQuery(selectAll , null);
if (cursor.moveToFirst()){
do {
Contact contact = new Contact();
contact.setId(cursor.getInt(0)); //<<<< CHANGED to use getInt
contact.setName(cursor.getString(2)); //<<<< CHANGED to skip first column
contact.setPhoneNumber(cursor.getString(3)); //<<<< CHANGED to skip first column
contactList.add(contact);
}while (cursor.moveToNext());
}
return contactList;
}
Then I suspect that you would get the expected results.
This gets the normally hidden actual rowid column as well as all the other columns; so there is an extra column at the start.
Note this assumes that you haven't defined the table using WITHOUT ROWID
Really you should consider the id/rowid as a long but int will work as long as there aren't too many rows.
However, this should only be a temporary fix.
The full/permanent fix should be
Code the first column so that it is defined as an alias of rowid e.g. using CREATE TABLE you_table_name (ID INTEGER PRIMARY KEY, the_other_columns...... (this assumes that the column name is ID).
Delete the database by either uninstalling the App or by deleting the App's data.
This assumes that you do not require the current data.
Change the contact class so that the Id member is long not int.
Change the getters and setters in the contact class (setId and I assume getId) so that the methods use long rather than int
Change any other uses of the Id member of the contact class to use long.
Change the getAllContact method to be
:-
public List<Contact> getAllContact(){
SQLiteDatabase db = this.getReadableDatabase();
List<Contact> contactList = new ArrayList<>();
String selectAll = "SELECT * FROM " + Util.TABLE_NAME;
Cursor cursor = db.rawQuery(selectAll , null);
if (cursor.moveToFirst()){
do {
Contact contact = new Contact();
contact.setId(cursor.getInt(0));
contact.setName(cursor.getString(1));
contact.setPhoneNumber(cursor.getString(2));
contactList.add(contact);
}while (cursor.moveToNext());
}
return contactList;
}
delete the App's Data or uninstall the App.
rerun the App

Executing multiline query does not work with table alias where single-line query does

This is my first time using ucanaccess since I just found out that my previous version of Eclipse would not work with Java 1.8 so I can get to my Access DB. I am familiar with Java programming and RDBMS (currently use Oracle) so I don't understand why I'm getting an error with my code.
This is the code I use to connect to the DB (variable dbFile is a File object used to store the Access DB path):
try
{
String urlDB = "jdbc:ucanaccess://"+ dbFile.getAbsolutePath();
Connection conn = DriverManager.getConnection(urlDB, "", "");
System.out.println("Connection Successful\n");
Statement test = conn.createStatement();
/* ResultSet rs = test.executeQuery("SELECT e.* "
+ "FROM Employees e"
+ "WHERE e.EmployeeNo LIKE 'H%'"
+ "ORDER BY e.LastName");
System.out.println(); //spacing
//retrieve column data
while(rs.next())
{
//can get data by column name instead of ID
String id = rs.getString("ID");
String fName = rs.getString("FirstName");
String lName = rs.getString("LastName");
String dName = rs.getString("DisplayName");
System.out.println(id + "\t" + fName + "\t" + lName + "\t");
}
*/
ResultSet rs = test.executeQuery("SELECT e.* FROM Employees e WHERE e.EmployeeNo LIKE '1%' ORDER BY e.LastName");
//get table information (i.e. column names)
ResultSetMetaData rsmd = rs.getMetaData();
int dbColumnCount = rsmd.getColumnCount();
/* //db columns starts at 1 not 0
for (int count = 1; count <= dbColumnCount; count++)
{
System.out.print(rsmd.getColumnName(count) + "\t");
}
*/
System.out.format("%5s%10s%15s%20s%n", rsmd.getColumnName(1), rsmd.getColumnName(2),
rsmd.getColumnName(3), rsmd.getColumnName(4));
//System.out.println();
while(rs.next())
{
//can get data by column name instead of ID
String id = rs.getString("ID");
String fName = rs.getString("FirstName");
String lName = rs.getString("LastName");
String dName = rs.getString("DisplayName");
//System.out.println(id + "\t" + fName + "\t" + lName + "\t");
System.out.format("%5s%10s%15s%20s%n", id, fName, lName, dName);
}
}
catch (Exception e)
{
e.printStackTrace();
System.err.println("Could not connect to the Database");
System.err.println(e.getMessage());
}
}
The first call to ResultSet(multiline query) throws the following exception:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.0 user lacks privilege or object not found: E
at net.ucanaccess.jdbc.UcanaccessStatement.executeQuery(UcanaccessStatement.java:210)
at DBConnect.<init>(InOutBoard.java:78)
at InOutBoard.main(InOutBoard.java:47)
Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: E
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.executeQuery(Unknown Source)
at net.ucanaccess.jdbc.UcanaccessStatement.executeQuery(UcanaccessStatement.java:208)
... 2 more
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: E
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.QuerySpecification.resolveColumnReferencesForAsterisk(Unknown Source)
at org.hsqldb.QuerySpecification.resolveReferences(Unknown Source)
at org.hsqldb.QueryExpression.resolve(Unknown Source)
at org.hsqldb.ParserDQL.compileCursorSpecification(Unknown Source)
at org.hsqldb.ParserCommand.compilePart(Unknown Source)
at org.hsqldb.ParserCommand.compileStatements(Unknown Source)
at org.hsqldb.Session.executeDirectStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 5 more
Could not connect to the Database
UCAExc:::4.0.0 user lacks privilege or object not found: E
whereas if I run the second call to ResultSet (single-line query), the data is properly returned from the table. Now as far as I can tell (other than spanning multiple lines in the first one) both queries are the same. So why is it that the first one throws the error? I can't imagine that the choice of formatting would make a difference, but as I said, I'm knew to using ucanaccess.
Any help would be appreciated. Thanks in advance!
The link I regularly give is valid here too:
How to debug dynamic SQL in VBA
You are concatenating a SQL string without checking it is correct.
ResultSet rs = test.executeQuery("SELECT e.* "
+ "FROM Employees e"
+ "WHERE e.EmployeeNo LIKE 'H%'"
+ "ORDER BY e.LastName");
will result in
SELECT e.* FROM Employees eWHERE e.EmployeeNo LIKE 'H%'ORDER BY e.LastName
It's missing spaces between the line breaks.

Comparing dates in jpa

I am trying to find results in a postgresql database between two dates (field described in ddbb as timestamp).
I have these three records which must meet target:
2016-03-04 00:00:00
2016-03-04 14:00:00
2016-03-04 10:56:00
final Calendar fechaMinima = Calendar.getInstance();
and set the parameters I want.
the jpa column is defined:
#Column(name = "tim_ofrecim")
#NotNull
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(style = "M-")
private Date Tewslofr.timOfrecim;
With JPA I try to find them with the following code:
#NamedQuery(name = "ofr_query2", query = "SELECT COUNT (*) FROM Tewslofr ofr "
+ "WHERE ofr.id.codIdprodto =:codIdprodto "
+ "AND ofr.codUser =:codUser "
+ "AND ofr.timOfrecim BETWEEN :timMinimo AND :timMaximo")
public static Long getMethod(final String codProducto,
final String codUser, final Calendar fechaMinima,
final Calendar fechaMaxima) {
return entityManager().createNamedQuery("ofr_query2", Long.class)
.setParameter("codIdprodto", codProducto)
.setParameter("codUser", codUser)
.setParameter("timMinimo", fechaMinima, TemporalType.TIMESTAMP)
.setParameter("timMaximo", fechaMaxima, TemporalType.TIMESTAMP)
.getSingleResult();
}
and obtain this exception:
Caused by: java.lang.IllegalArgumentException: Parameter value [java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Paris",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=184,lastRule=java.util.SimpleTimeZone[id=Europe/Paris,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2016,MONTH=2,WEEK_OF_YEAR=10,WEEK_OF_MONTH=2,DAY_OF_MONTH=1,DAY_OF_YEAR=67,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=8,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=434,ZONE_OFFSET=3600000,DST_OFFSET=0]] was not matching type [java.util.Date]
The stack trace to this is:
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Paris",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=184,lastRule=java.util.SimpleTimeZone[id=Europe/Paris,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2016,MONTH=2,WEEK_OF_YEAR=10,WEEK_OF_MONTH=2,DAY_OF_MONTH=1,DAY_OF_YEAR=67,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=9,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=170,ZONE_OFFSET=3600000,DST_OFFSET=0]] was not matching type [java.util.Date]; nested exception is java.lang.IllegalArgumentException: Parameter value [java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Paris",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=184,lastRule=java.util.SimpleTimeZone[id=Europe/Paris,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2016,MONTH=2,WEEK_OF_YEAR=10,WEEK_OF_MONTH=2,DAY_OF_MONTH=1,DAY_OF_YEAR=67,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=9,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=170,ZONE_OFFSET=3600000,DST_OFFSET=0]] was not matching type [java.util.Date]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:301)
at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:15)
at com.bbva.arq.front.spring.ewsl.ofrecimientos.api.v1.domain.Tewslofr.getCuentaOfrecimientosAgente_aroundBody2(Tewslofr.java:49)
at com.bbva.arq.front.spring.ewsl.ofrecimientos.api.v1.domain.Tewslofr.getCuentaOfrecimientosAgente(Tewslofr.java:1)
at com.bbva.arq.front.spring.ewsl.ofrecimientos.api.v1.daos.ofrecimientos.impl.OfrecimientosDAOImpl.getMethod(OfrecimientosDAOImpl.java:52)...
Caused by: java.lang.IllegalArgumentException: Parameter value [java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Paris",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=184,lastRule=java.util.SimpleTimeZone[id=Europe/Paris,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2016,MONTH=2,WEEK_OF_YEAR=10,WEEK_OF_MONTH=2,DAY_OF_MONTH=1,DAY_OF_YEAR=67,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=9,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=170,ZONE_OFFSET=3600000,DST_OFFSET=0]] was not matching type [java.util.Date]
at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:360)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:414)
If I change to DATE instead of TIMESTAMP:
public static Long getMethod(final String codProducto,
final String codUser, final Calendar fechaMinima,
final Calendar fechaMaxima) {
return entityManager().createNamedQuery("ofr_query2", Long.class)
.setParameter("codIdprodto", codProducto)
.setParameter("codUser", codUser)
.setParameter("timMinimo", fechaMinima.getTime(), TemporalType.DATE)
.setParameter("timMaximo", fechaMaxima.getTime(), TemporalType.DATE)
.getSingleResult();
}
the code returns 0.
Any help will be appreciated.
kindest regards
I still don't know why the first option does not work, but I have made it work with the option of Date. This option was correct but was returning 0 because of de codIdprodto, not because of the dates.