Search code examples
javams-accessintegerjackcess

Jackcess addRow() cannot insert a Java 'long' value


I'm trying to add a row with id number 3791318595.

long l = 3791318595L;
myTable.addRow(l,"testing");

however Jackcess transforms it into an integer and cuts to its max value:

2,147,483,647.

How can I correctly add the above number with Jackcess?


Solution

  • If the "id number" field in the Access table is defined as Number (Long Integer) then the short answer to your question is:

    You can't.

    A Long Integer in Access is a 32-bit signed integer whose maximum value is (2^31)-1 as you have seen. That is, a Long Integer in Access corresponds to int (not long) in Java. The value you are trying to insert into the Access field simply will not fit "as is", so there is no way that Jackcess (or any other application) can do it.

    If your "id numbers" are all positive integers then one possible workaround would be to have your code mimic unsigned 32-bit integers by wrapping values between 2,147,483,648 and 4,294,967,296 to their non-positive signed values:

    long unsignedAdjustment = 4294967296L;  // 2^32
    long l = 3791318595L;  // our test value
    if (l > unsignedAdjustment) {
        System.out.println("Error: ID value too large to fit, even if wrapped to non-positive integer.");
    }
    else {
        int signedID = 0;
        if (l > 2147483647L) {  // (2^31)-1
            signedID = (int) (l - unsignedAdjustment);
        }
        else {
            signedID = (int) l;
        }
        myTable.addRow(signedID, "testing");
    }
    

    That would store the row in the Access table with an "id number" of -503,648,701. Of course...

    1. it would be up to your code to perform the corresponding conversion when retrieving rows, and

    2. this approach has obvious implications for searching and ordering by "id number"

    ...but if the "id number" is really just a unique row identifier then it may not be too much of an inconvenience.