Comparing dates in jpa - 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.
Related
dynamically choose columns in select with R2DB2
I have been trying to pass the columns I want to select in but out of the box it appears it is not possible. I have tried things like #Query("SELECT :columns FROM USERS u WHERE u.LOCALE = :locale AND u.id IN (:ids)") Flux<Users> retrieveExportData(#Param("columns") String columns, #Param("locale") String locale, #Param("ids") String[] ids); and with private final R2dbcEntityTemplate template; I tried to create my own query and but that was not working because it has to be of type Criteria and that was just creating a complexity that just was not worth it. It would be nice if I could add the columns like criteriaList.add( Criteria.where("LOCALE").is(locale) ); Criteria criteria = Criteria.from(criteriaList); and execute it like Flux<Users> users = this.template.select(User.class) .matching(Query.query(criteria)) .all(); or just calling the repository like in my first example. Has anyone been able to do this successfully? ----- update 1 ----- I tried doing like so: import org.springframework.r2dbc.core.DatabaseClient; DatabaseClient databaseClient = DatabaseClient.create(connectionFactory); String sql = "SELECT " + columns + " FROM USERS u WHERE u.LOCALE=" + locale + " AND u.id IN (" + ids + ")"; return databaseClient.sql(sql) .fetch() .all().cast(User.class); but Since Spring 4.3.6.RELEASE, LinkedCaseInsensitiveMap doesn't extend LinkedHashMap and HashMap, but only implements Map interface. This results in a Cannot cast org.springframework.util.LinkedCaseInsensitiveMap to User at java.base/java.lang.Class.cast error. I then tried the jooq approach suggested in the answers but it just produces syntax errors. Example private final DSLContext ctx = DSL.using(connectionFactory); private final Users users = ctx.newRecord(Users.USERS); <-- USERS not found #Query("SELECT :columns FROM USERS u WHERE u.LOCALE = :locale AND u.id IN (:ids)") public Flux<Users> retrieveExportData( List<Field<?>> columns, String locale, String[] ids ) { return Flux.from(ctx .select(columns) .from("USERS") .where(users.LOCALE.eq(locale)) <--- LOCALE not found .and(users.ID.in(ids)) <--- ID not found ).map(r -> r.into(Users.class)); <---- into not found } the library look promising. I will try to get it working.
You cannot replace a bind parameter (:columns) by syntactic elements like this, other than actual bind values. For this type of dynamic SQL, you'll have to resort to some sort of query building mechanism. Perhaps look at jOOQ, which has R2DBC support? Your implementation would then look like this: #Query("SELECT :columns FROM USERS u WHERE u.LOCALE = :locale AND u.id IN (:ids)") public Flux<Users> retrieveExportData( List<Field<?>> columns, String locale, String[] ids ) { return Flux.from(ctx .select(columns) .from(USERS) .where(USERS.LOCALE.eq(locale)) .and(USERS.ID.in(ids)) ).map(r -> r.into(Users.class)); } Disclaimer: I work for the company behind jOOQ.
you can write dynamic SQL like so. import org.springframework.r2dbc.core.DatabaseClient; DatabaseClient databaseClient = DatabaseClient.create(connectionFactory); String sql = "SELECT " + columns + " FROM USERS u WHERE u.LOCALE=" + locale + " AND u.id IN (" + ids + ")"; return databaseClient.sql(sql) .fetch() .all().cast(User.class); and you will need this dependency implementation "org.springframework.boot:spring-boot-starter-data-r2dbc:2.6.2"
How to compare Date in criteriaBuilder.greaterThan()?
I'm fixing a bug in JAVA/Angular Project, I'm getting a Date in Millisecodes from the front End, then I change the date from Millisecondes to "yyyy MM dd HH:mm:ss" format using SimpleDateFormat class in JAVA. I want to compare the date that I'm getting from the front end with a field in a Table in my DataBase using criteriaBuilder.greaterThan(). The type of the field is bigInit(20). I proposed as a solution to compare the dates using TimesTamp type, but the request from the client is a comparaison using Date in JAVA public Specification<T> greater(Object value, String field, String type) { return (root, criteriaQuery, criteriaBuilder) -> { Path tuple = getPath(root, field); System.out.println("type" + tuple.getJavaType()); if (tuple.getJavaType().isAssignableFrom(Date.class)) { return criteriaBuilder.greaterThan(tuple, convertFilterDateToDate(value.toString())); } return criteriaBuilder.greaterThan(getPath(root,field),Double.valueOf(value.toString())); }; } This method takes 3 parametrs : Object value : its type is Long in my case, it is the value of the date taken from the front End, I wrote a method to convert the value from Long to Date using SimpleDateFormat. String field: its the field in my table, it contains dates with type Long. String Type: it contains the value 'endDate' in my case. Below, the definition of getPath Method : public Path getPath(Root<T> root, String field){ String fiedls[] = field.split("\\."); if(!field.contains(".")){ System.out.print(root.get(field)); return root.get(field); } else if (fiedls.length==2){ Join<Operation,Object> join = root.join(fiedls[0]); return join.get(fiedls[1]); } else if(fiedls.length==3){ Join<Operation,Object> join = root.join(fiedls[0]); Join<Object,Object> join1 = join.join(fiedls[1]); return join1.get(fiedls[2]); } return null; } The request is to compare date using Date type in java and criteriaBuilder.greaterThan() , any Idea ?
offset time (time with time zone) in jdbc PostgreSQL
I am trying to save and retrieve java.time.OffsetTime into PostgreSQL version 10.5, JDBC driver latest (v 42.2.5). The Offset time is saved but with an invalid offset (it takes app server offset instead of the passed offset). According to: https://jdbc.postgresql.org/documentation/head/8-date-time.html TIME WITH TIMEZONE is not supported (yet?). Note that ZonedDateTime, Instant and OffsetTime / TIME [ WITHOUT TIMEZONE ] are not supported My question, is I want to save offset time into Postgres, so what are alternatives? Note, I only care about time (it is actually a timetable) but I need to know the offset as well for comparing reasons with current_time. My Example: public class Customer { #Id #GeneratedValue private Long id; private String name; #Column(columnDefinition = "time with time zone") private OffsetTime serviceTime; #Column(columnDefinition = "timestamp with time zone") private OffsetDateTime serviceDateTime; private Instant createdDate = Instant.now(); } The main: { OffsetTime serviceTime = OffsetTime.parse("10:00+02:00"); OffsetDateTime serviceDateTime = OffsetDateTime.now().with(serviceTime); System.out.println(serviceTime); System.out.println(serviceDateTime); Customer customer = new Customer().withName("wael") .withServiceTime(serviceTime) .withServiceDateTime(serviceDateTime); System.out.println("customer: " + customer); customerRepository.save(customer); } { Customer dbCustomer = customerRepository.findById(1L).get(); OffsetTime dbServiceTime = dbCustomer.getServiceTime(); OffsetDateTime dbServiceDateTime = dbCustomer.getServiceDateTime(); System.out.println(dbServiceTime); System.out.println(dbServiceDateTime); System.out.println("from db customer: " + dbCustomer); } Database: id created_date name service_date_time service_time 1 2018-10-15 10:38:27.814000 wael 2018-10-15 08:00:00.000000 10:00:00 +03:00 Output: 10:00+02:00 2018-10-15T10:00+02:00 customer: Customer(id=null, name=wael, serviceTime=10:00+02:00, serviceDateTime=2018-10-15T10:00+02:00, createdDate=2018-10-15T07:10:59.900Z) 10:00+03:00 2018-10-15T11:00+03:00 from db customer: Customer(id=1, name=wael, serviceTime=10:00+03:00, serviceDateTime=2018-10-15T11:00+03:00, createdDate=2018-10-15T07:10:59.900Z) Note, my machine timezone is +3 (hence the printed information from db is +3), and my database server is a docker image with UTC datetime settings. Observations: The OffsetDatetime is saved correctly (as UTC) and retrieved correctly. The OffsetTime is saved incorrect (it should be 10:00:00 +02:00 or 11:00:00 +03:00 or even 08:00:00 +00:00 not 10:00:00 +03:00, and retrieved incorrect!)
With JPA 2.2, you can also use OffsetTime in Postgresql. #Column(name = "offset_time", columnDefinition = "TIME WITH TIME ZONE") private OffsetTime offsetTime; That's how it is stored in my database: 22:00:00.000000 +02:00
java.time.format.DateTimeParseException: Text '1963-03-24T00:00:00.000+01:00' could not be parsed at index 19 1000
I get the datetime value as: 1963-03-24T00:00:00.000+01:00 I am using Java 8 to parse the date time as following: public static final DateTimeFormatter ISO_OFFSET_DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX ZD"); public static ZonedDateTime parseDateTime(String date) { return parseDateTime(date, ISO_OFFSET_DATE_TIME); } public static ZonedDateTime parseDateTime(String date, DateTimeFormatter format) { if (date == null) { return null; } return ZonedDateTime.parse(date, format); } When I run this, I get this error: Caused by: java.time.format.DateTimeParseException: Text '1963-03-24T00:00:00.000+01:00' could not be parsed at index 19 at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) ~[?:1.8.0_112] at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) ~[?:1.8.0_112] at java.time.ZonedDateTime.parse(ZonedDateTime.java:597) ~[?:1.8.0_112] What's wrong with my pattern ?
Use the following Date Formatter: DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); instead of: DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX ZD"); The last part of your time input is .000+0100 which comprises of a dot, milliseconds & timezone. The dot can be represented as it is i.e. . The millis .000 can be parsed by .SSS, and the timezone +01:00 can be parsed by XXX.
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