importjava.io.File;importcom.healthmarketscience.jackcess.*;publicclassjackcessTest{publicstaticvoidmain(String[]args){StringnewEmp_Id="GT001";// test dataStringnewEmp_Name="Gord";booleaninsertedOK=false;intcounter=1;StringinsertEmp_Id=newEmp_Id;try{Tabletable=DatabaseBuilder.open(newFile("C:\\__tmp\\jTest\\jTest.accdb")).getTable("Employee");while(!insertedOK){try{table.addRow(insertEmp_Id,newEmp_Name);insertedOK=true;System.out.println(String.format("New record inserted as %s",insertEmp_Id));}catch(Exceptione){insertEmp_Id=String.format("%s_copy%s",newEmp_Id,counter++);}}}catch(Exceptione){e.printStackTrace();}}}
It displays the following
New record inserted as GT001
So far, so good. Now run the Java code again. It displays
New record inserted as GT001_copy1
Launch Access and open the [Employee] table. All looks normal:
Close Access. Now run the following VBScript
OptionExplicitDimcon,rstSetcon=CreateObject("ADODB.Connection")con.Open"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\__tmp\jTest\jTest.accdb;"Setrst=CreateObject("ADODB.Recordset")rst.Open"SELECT Emp_Id, Emp_Name FROM Employee",conDoUntilrst.EOFWScript.Echorst("Emp_Id").Value&": "&rst("Emp_Name").Valuerst.MoveNextLooprst.CloseSetrst=Nothingcon.CloseSetcon=Nothing
I first noticed this when working with a DAO connection in Access itself, but this VBScript replicates the issue with a completely independent ADO connection.
I am using jackcess-2.0.1.jar under JavaSE-1.7.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Before performing the Compact and Repair, the "phantom records" are also visible to Jackcess itself if I run through the table directly...
for(Rowrow:table){System.out.println(String.format("Column 'Emp_Id' has value: %s",row.get("Emp_Id")));}
...which gives me...
Column 'Emp_Id' has value: GT001
Column 'Emp_Id' has value: GT001
Column 'Emp_Id' has value: GT001_copy1
Column 'Emp_Id' has value: GT001
Column 'Emp_Id' has value: GT001_copy1
Column 'Emp_Id' has value: GT001_copy2
...but not if I cycle through the records using cursor backed by the Primary Key index...
for(Rowrow:CursorBuilder.createCursor(table.getPrimaryKeyIndex())){System.out.println(String.format("Column 'Emp_Id' has value: %s",row.get("Emp_Id")));}
...yielding
Column 'Emp_Id' has value: GT001
Column 'Emp_Id' has value: GT001_copy1
Column 'Emp_Id' has value: GT001_copy2
If you would like me to create a bug ticket for this just let me know.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
yeah, that would be great if you could file an issue.
basically, jackcess adds the row to the table before updating the indexes. so, if the unique constraint fails, the row will already be in the table (although it won't be in the index). jackcess really needs to pre-check the indexes before writing the row to the table.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Okay, this is weird. In Access 2010, create a new database named "jTest.accdb" and then run the following query to create a table
Close Access 2010. Run the following Java code
It displays the following
So far, so good. Now run the Java code again. It displays
Launch Access and open the [Employee] table. All looks normal:
Close Access. Now run the following VBScript
It returns
Note that 'GT001' is the primary key, so there is no way that it should appear twice.
Run the Java code again.
Run the VBScript again
However, if we open the database in Access the [Employee] table looks fine:
Now do a "Compact and Repair" on the database in Access. Run the VBScript
The "phantom records" have disappeared.
I first noticed this when working with a DAO connection in Access itself, but this VBScript replicates the issue with a completely independent ADO connection.
I am using jackcess-2.0.1.jar under JavaSE-1.7.
Additional information:
Before performing the Compact and Repair, the "phantom records" are also visible to Jackcess itself if I run through the table directly...
...which gives me...
...but not if I cycle through the records using cursor backed by the Primary Key index...
...yielding
If you would like me to create a bug ticket for this just let me know.
yeah, that would be great if you could file an issue.
basically, jackcess adds the row to the table before updating the indexes. so, if the unique constraint fails, the row will already be in the table (although it won't be in the index). jackcess really needs to pre-check the indexes before writing the row to the table.
Either that, or perhaps go back and flag the record as "deleted" if something bad happens while updating the indexes.
Anyway, I have created the ticket. Thanks for your reply (and for Jackcess, too!).
Bug filed here: https://sourceforge.net/p/jackcess/bugs/99/
Will be fixed in the 2.0.2 release.