I am having a problem with repeating previous operations when there is an error in the SaveChanges method of Entity Framework.
Below is the code block
public static int SaveChangesTask(this DbContext db)
{
int result = -1;int countLoop = 0;
bool continueLoop = true;
var modifiedOrAddedEntities = db.ChangeTracker.Entries().Where(a => a.State != EntityState.Detached
&& a.State != EntityState.Unchanged).ToList();
while (continueLoop && countLoop<3)
{
try
{
result= db.SaveChanges();
continueLoop = false;
}
catch(Exception ex)
{
string error = ex.ToSystemException();
if(error.ToLowerInvariant().Contains("ORA-00060".ToLowerInvariant()) || error.ToLowerInvariant().Contains("deadlock"))
{
foreach (var item in modifiedOrAddedEntities)
{
db.Entry(item).State = item.State;
}
countLoop++;
Random rnd = new Random();
System.Threading.Thread.Sleep(rnd.Next(1, 5)* 1000);
}
else
{
throw ex;
}
}
}
return result;
}
But when I want to add old tracking objects to context, Entity Framework Throws Exception like that
"The entity type DbEntityEntry is not part of the model for the current context"
I'm currently working on a generic function for inserting data tables via entity framework. However, with my current solution I ended up with a ton of very repetitive code with only a few minor differences. I would like to simplify what I have and remove the need for large case statements based on my table names (I only included two cases in this example to save space).
Here is what I currently have:
public static void InsertByTable(IEnumerable<DataTable> chunkedTable, string tableName)
{
switch (tableName)
{
#region Parcel
case TaxDataConstant.Parcel:
Parallel.ForEach(
chunkedTable,
new ParallelOptions
{
MaxDegreeOfParallelism = Convert.ToInt32(ConfigurationManager.AppSettings["MaxThreads"])
},
chunk =>
{
Realty_Records_ProdEntities entities = null;
try
{
entities = new Realty_Records_ProdEntities();
entities.Configuration.AutoDetectChangesEnabled = false;
foreach (DataRow dr in chunk.Rows)
{
var parcelToInsert = new Parcel();
foreach (DataColumn c in dr.Table.Columns)
{
SetProperty(parcelToInsert, c.ColumnName, dr[c.ColumnName]);
}
entities.Parcels.Add(parcelToInsert);
}
entities.SaveChanges();
}
catch (Exception ex)
{
TaxDataError.AddTaxApplicationLog(
TaxDataConstant.CategoryError,
ex.Source,
ex.Message,
ex.StackTrace);
throw;
}
finally
{
entities?.Dispose();
}
});
break;
#endregion
#region Asmt
case TaxDataConstant.Asmt:
Parallel.ForEach(
chunkedTable,
new ParallelOptions
{
MaxDegreeOfParallelism = Convert.ToInt32(ConfigurationManager.AppSettings["MaxThreads"])
},
chunk =>
{
Realty_Records_ProdEntities entities = null;
try
{
entities = new Realty_Records_ProdEntities();
entities.Configuration.AutoDetectChangesEnabled = false;
foreach (DataRow dr in chunk.Rows)
{
var asmtToInsert = new Asmt();
foreach (DataColumn c in dr.Table.Columns)
{
SetProperty(asmtToInsert, c.ColumnName, dr[c.ColumnName]);
}
entities.Asmts.Add(asmtToInsert);
}
entities.SaveChanges();
}
catch (Exception ex)
{
TaxDataError.AddTaxApplicationLog(
TaxDataConstant.CategoryError,
ex.Source,
ex.Message,
ex.StackTrace);
throw;
}
finally
{
entities?.Dispose();
}
});
break;
#endregion
}
}
Is there any way I can make this table agnostic?
You can probably move the logic in the case statement to a helper extension method which is generic. something like this (untested) pseudo code:
public static class EntityAdder
{
public static void AddEntities<T>(this IEnumerable<DataTable> chunkedEntities, Action<Realty_Records_ProdEntities, T entity> addingFunction)
{
Parallel.ForEach(
chunkedTable,
new ParallelOptions
{
MaxDegreeOfParallelism = Convert.ToInt32(ConfigurationManager.AppSettings["MaxThreads"])
},
chunk =>
{
Realty_Records_ProdEntities entities = null;
try
{
entities = new Realty_Records_ProdEntities();
entities.Configuration.AutoDetectChangesEnabled = false;
foreach (DataRow dr in chunk.Rows)
{
var toInsert = new T();
foreach (DataColumn c in dr.Table.Columns)
{
SetProperty(parcelToInsert, c.ColumnName, dr[c.ColumnName]);
}
addingFunction(entities,toInsert);
}
entities.SaveChanges();
}
catch (Exception ex)
{
TaxDataError.AddTaxApplicationLog(
TaxDataConstant.CategoryError,
ex.Source,
ex.Message,
ex.StackTrace);
throw;
}
finally
{
entities?.Dispose();
}
});
}
}
this could then be used something like this:
public static void InsertByTable(IEnumerable<DataTable> chunkedTable, string tableName)
{
switch (tableName)
{
#region Parcel
case TaxDataConstant.Parcel:
chunkedTable.AddEntities((entities,newEntity)=> entities.Parcels.Add(newEntity))
break;
#endregion
#region Asmt
case TaxDataConstant.Asmt:
chunkedTable.AddEntities((entities,newEntity)=> entities.Asmts.Add(newEntity))
break;
#endregion
}
}
you might be able to automate the adding bit by finding the property on the class which is a list of the things you want to add and avoid passing the action in if you wanted.
Based on Sams response and some further research I was able to refactor out the case statement.
Here's my solution:
public static void InsertByTable(IEnumerable<DataTable> chunkedTable, Type type)
{
Parallel.ForEach(
chunkedTable,
new ParallelOptions
{
MaxDegreeOfParallelism = Convert.ToInt32(ConfigurationManager.AppSettings["MaxThreads"])
},
chunk =>
{
Realty_Records_ProdEntities entities = null;
try
{
entities = new Realty_Records_ProdEntities();
entities.Configuration.AutoDetectChangesEnabled = false;
var set = entities.Set(type);
foreach (DataRow dr in chunk.Rows)
{
var objectToInsert = Activator.CreateInstance(type);
foreach (DataColumn c in dr.Table.Columns)
{
SetProperty(objectToInsert, c.ColumnName, dr[c.ColumnName]);
}
set.Add(objectToInsert);
}
entities.SaveChanges();
}
catch (Exception ex)
{
TaxDataError.AddTaxApplicationLog(
TaxDataConstant.CategoryError,
ex.Source,
ex.Message,
ex.StackTrace);
throw;
}
finally
{
entities?.Dispose();
}
});
}
On some phones when I use the camera to load a new photo into an ImageView, the data I get back is null. On other phones it works fine. It works on most Kitkat phone's, but not on a Nexus 7 (4.4.2) and who know's on what else.
Works on HTC M8 (5.0.1), HTC Desire X (4.1.1), Samsung Galaxy S4 (4.4.2), Samsung Galaxy S5 (5.0).
I share only the code for capturing images on Kitkat, but I handle them differently when I am working with bitmap conversions and upload to server.
btn_camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Log.i("INTENT0", "PICK_FROM_CAMERA_KITKAT");
Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intentPicture,PICK_FROM_CAMERA_KITKAT);
dialog_newimg.dismiss();
}
});
#SuppressLint("NewApi")
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) return;
switch (requestCode) {
case PICK_FROM_CAMERA_KITKAT:
if (data != null) {
Log.i("data.getData()", data.getData() + ""); //null
[...many things..]
}
...
}
}
I read some similar questions and I highlight that I don't use EXTRA_OUTPUT in any way.
Any ideas?
I did something like this. Actually the key is to handle the Uri differently:
if (data.getData() == null) {
selectedImageUri = Uri.fromFile(imageFileForCamera_);
} else {
selectedImageUri = data.getData();
}
After this it's also important to handle the path differently with the helper functions getRealPathFromURI() for above Kitkat and getPath() for below Kitkat.
I post my whole code here as a reference for others. This code has been working for 2 months now in all kinds of devices of hundreds of users without force closes.
case PICK_FROM_CAMERA_COMPLETE:
if(resultCode == RESULT_OK) {
if (data != null) {
if (data.getData() == null) {
selectedImageUri = Uri.fromFile(imageFileForCamera_);
} else {
selectedImageUri = data.getData();
}
} else {
selectedImageUri = Uri.fromFile(imageFileForCamera_);
}
complete_dialog.filename = getRealPathFromURI(selectedImageUri);
Bitmap bitmapSelectedImage;
try {
bitmapSelectedImage = getSampleBitmapFromFile(getRealPathFromURI(selectedImageUri), 400, 400);
ExifInterface exifInterface = new ExifInterface(getRealPathFromURI(selectedImageUri));
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(orientation);
Matrix matrix = new Matrix();
if (rotationInDegrees != 0f) {
matrix.preRotate(rotationInDegrees);
bitmapSelectedImage = Bitmap.createBitmap(bitmapSelectedImage, 0, 0, bitmapSelectedImage.getWidth(), bitmapSelectedImage.getHeight(), matrix, true);
}
Bitmap d = new BitmapDrawable(getApplicationContext().getResources(), bitmapSelectedImage).getBitmap();
int nh = (int) ( d.getHeight() * (512.0 / d.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(d, 512, nh, true);
complete_dialog.iv_bucket2.setImageBitmap(scaled);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if(resultCode == RESULT_CANCELED){
//DELETE FILE THAT WE CREATED FROM CAMERA
}
break;
case PICK_FROM_CAMERA_COMPLETE_KITKAT:
if(resultCode == RESULT_OK) {
if (data != null) {
if (data.getData() == null) {
selectedImageUri = Uri.fromFile(imageFileForCamera_);
} else {
selectedImageUri = data.getData();
}
} else {
selectedImageUri = Uri.fromFile(imageFileForCamera_);
}
Bitmap bitmapSelectedImage2;
try {
bitmapSelectedImage2 = getSampleBitmapFromFile(getPath(BucketProfileActivity.this, selectedImageUri), 400, 400);
ExifInterface exifInterface = new ExifInterface(getPath(BucketProfileActivity.this, selectedImageUri));
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(orientation);
Matrix matrix = new Matrix();
if (rotationInDegrees != 0f) {
matrix.preRotate(rotationInDegrees);
bitmapSelectedImage2 = Bitmap.createBitmap(bitmapSelectedImage2, 0, 0, bitmapSelectedImage2.getWidth(), bitmapSelectedImage2.getHeight(), matrix, true);
}
Bitmap d = new BitmapDrawable(getApplicationContext().getResources(), bitmapSelectedImage2).getBitmap();
int nh = (int) ( d.getHeight() * (512.0 / d.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(d, 512, nh, true);
complete_dialog.iv_bucket2.setImageBitmap(scaled);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if(resultCode == RESULT_CANCELED){
//DELETE FILE THAT WE CREATED FROM CAMERA
}
break;
case LOAD_FROM_GALLERY_COMPLETE: //before KitKat
if(resultCode == RESULT_OK) {
if (data != null) {
complete_dialog.show();
Uri imageuri = data.getData();
complete_dialog.filename = getRealPathFromURI(imageuri);
Bitmap bitmapSelectedImage3;
try {
bitmapSelectedImage3 = getSampleBitmapFromFile(getRealPathFromURI(imageuri), 400, 400);
ExifInterface exifInterface = new ExifInterface(getRealPathFromURI(imageuri));
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(orientation);
Matrix matrix = new Matrix();
if (rotationInDegrees != 0f) {
matrix.preRotate(rotationInDegrees);
bitmapSelectedImage3 = Bitmap.createBitmap(bitmapSelectedImage3, 0, 0, bitmapSelectedImage3.getWidth(), bitmapSelectedImage3.getHeight(), matrix, true);
}
Bitmap d = new BitmapDrawable(getApplicationContext().getResources(), bitmapSelectedImage3).getBitmap();
int nh = (int) ( d.getHeight() * (512.0 / d.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(d, 512, nh, true);
complete_dialog.iv_bucket2.setImageBitmap(scaled);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else if(resultCode == RESULT_CANCELED){
//DELETE FILE THAT WE CREATED FROM CAMERA
}
break;
case LOAD_FROM_GALLERY_KITKAT_COMPLETE: //after KitKat if(resultCode == RESULT_OK) {
if (data != null) {
complete_dialog.show();
Uri imageuri = data.getData();
complete_dialog.filename = getPath(BucketProfileActivity.this, imageuri);
Bitmap bitmapSelectedImage4;
try {
bitmapSelectedImage4 = getSampleBitmapFromFile(getPath(BucketProfileActivity.this, imageuri), 400, 400);
ExifInterface exifInterface = new ExifInterface(getPath(BucketProfileActivity.this, imageuri));
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(orientation);
Matrix matrix = new Matrix();
if (rotationInDegrees != 0f) {
matrix.preRotate(rotationInDegrees);
bitmapSelectedImage4 = Bitmap.createBitmap(bitmapSelectedImage4, 0, 0, bitmapSelectedImage4.getWidth(), bitmapSelectedImage4.getHeight(), matrix, true);
}
Bitmap d = new BitmapDrawable(getApplicationContext().getResources(), bitmapSelectedImage4).getBitmap();
int nh = (int) ( d.getHeight() * (512.0 / d.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(d, 512, nh, true);
complete_dialog.iv_bucket2.setImageBitmap(scaled);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else if(resultCode == RESULT_CANCELED){
//DELETE FILE THAT WE CREATED FROM CAMERA
}
break;
Helper functions:
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, "", null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
//Log.i("IDX", idx + "");
// Log.i("RESULT", cursor.getString(idx) + "");
result = cursor.getString(idx); //force close here
cursor.close();
}
return result;
}
#TargetApi(Build.VERSION_CODES.KITKAT) #SuppressLint("NewApi")
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #param selection (Optional) Filter used in the query.
* #param selectionArgs (Optional) Selection arguments used in the query.
* #return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
this is log:
08-28 13:50:47.648: A/libc(1010): ### ABORTING: INVALID HEAP ADDRESS IN dlfree addr=0x2a26bc90
08-28 13:50:47.648: A/libc(1010): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 1020 (FinalizerDaemon)
08-28 13:50:48.698: W/ActivityManager(149): Scheduling restart of crashed service com.android.KnowingLife/.PushNotification.NotificationService in 5000ms
08-28 13:50:48.698: W/ActivityManager(149): Force removing ActivityRecord{412a2c70 com.android.KnowingLife/.PhoneSynActivity}: app died, no saved state
08-28 13:50:48.807: W/GpsLocationProvider(149): Unneeded remove listener for uid 1000
08-28 13:50:49.257: E/Trace(1064): error opening trace file: No such file or directory (2)
08-28 13:50:50.017: W/GpsLocationProvider(149): Duplicate add listener for uid 10044
08-28 13:50:52.827: W/InputMethodManagerService(149): Got RemoteException sending setActive(false) notification to pid 1010 uid 10044
I run it in my emulator( version 4.1),and I am bulk inserting contacts to local .It works well usual,but I got 600 more contacts to
insert to local ,it doesn't work when insert to about 6%.I don't know
how to show it to you ,this is my code ,look this, you will see the
problem,thank
/**
* insert
*/
class InsertContactsTask extends AsyncTask<Void, Integer, Integer> {
String detail;
public InsertContactsTask(String detail) {
this.detail = detail;
}
#SuppressWarnings("deprecation")
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(PROGRESS_DIALOG);
}
#Override
protected Integer doInBackground(Void... params) {
String[] itemRecord = detail.split(ParseData.getInstance()
.getRecordSplitFalg(), -1);
int count = itemRecord.length;
wait_Dialog.setMax(count);
ArrayList<ContentProviderOperation> contentOper = null;
contentOper = new ArrayList<ContentProviderOperation>();
for (int i = 0; i < itemRecord.length; i++) {
int rawContactInsertIndex = contentOper.size();
String[] item = null;
try {
item = itemRecord[i].split(ParseData.getInstance()
.getFiledSplitFlag(), -1);
contentOper.add(ContentProviderOperation
.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, null)
.withValue(RawContacts.ACCOUNT_NAME, null).build());
contentOper.add(ContentProviderOperation
.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID,
rawContactInsertIndex)
.withValue(Data.MIMETYPE,
StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME, item[0])
.build());
for (int j = 1; j < item.length; j++) {
if (item[j].startsWith("1")) {
String phoneType = item[j].substring(1, 2);
int iType;
String label = null;
if (phoneType.compareToIgnoreCase("a") >= 0)
iType = phoneType.compareToIgnoreCase("a") + 10;
else
iType = Integer.parseInt(phoneType);
if (iType == 0)
label = item[j + 1];
contentOper
.add(ContentProviderOperation
.newInsert(
android.provider.ContactsContract.Data.CONTENT_URI)
.withValueBackReference(
Data.RAW_CONTACT_ID,
rawContactInsertIndex)
.withValue(Data.MIMETYPE,
Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER,
item[j].substring(2))
// "data1"
.withValue(Phone.TYPE, iType)
.withValue(Phone.LABEL, label)
.build());
if (iType == 0)
j++;
} else {
String emailType = item[j].substring(1, 2);
int iEmailType = Integer.parseInt(emailType);
String emailLabel = null;
if (iEmailType == 0)
emailLabel = item[j + 1];
contentOper
.add(ContentProviderOperation
.newInsert(
android.provider.ContactsContract.Data.CONTENT_URI)
.withValueBackReference(
Data.RAW_CONTACT_ID,
rawContactInsertIndex)
.withValue(Data.MIMETYPE,
Email.CONTENT_ITEM_TYPE)
.withValue(Email.DATA,
item[j].substring(2))
.withValue(Email.TYPE, iEmailType)
.withValue(Email.LABEL, emailLabel)
.build());
if (iEmailType == 0)
j++;
}
}
int iUpdate = i + 1;
if (iUpdate % 20 == 0 || iUpdate == itemRecord.length) {
try {
#SuppressWarnings("unused")
ContentProviderResult[] results = PhoneSynActivity.this
.getContentResolver().applyBatch(
ContactsContract.AUTHORITY,
contentOper);
contentOper.clear();
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
publishProgress(i);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
return count;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
wait_Dialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Integer count) {
super.onPostExecute(count);
wait_Dialog.dismiss();
txt_count.setText( count+ "");
Toast.makeText(PhoneSynActivity.this,
R.string.string_download_suc, Toast.LENGTH_LONG).show();
}
}
I have a problem. When I try to use the "Select distinct" in HSQLDB, the stream of results returns me all rows instead of me returning only distinct rows.
I've tried the following syntax:
SELECT DISTINCT FROM ratings UserID order by UserID;
SELECT DISTINCT (UserID) FROM ratings order by UserID;
SELECT DISTINCT UserID FROM ratings;
SELECT DISTINCT (UserID) FROM ratings;
None of them works. What is the problem?
If anyone able to help me I appreciate.
Thank you.
The function code where I perform the action is as follows:
private void readUserFile(String filename) {
try {
//Verify if file users exists
boolean exists = (new File(filename)).exists();
if (!exists) {
//If file users not exists create one, bases on distinct users that exist in ratings table
ResultSet rsUsers = jdbcTemplate.getDataSource().getConnection().createStatement().executeQuery("SELECT DISTINCT UserID FROM ratings order by UserID;");
List<String> users = new ArrayList<String>();
while (rsUsers.next()) {
users.add(String.valueOf(rsUsers.getInt(1)));
}
rsUsers.close();
//Create and write to file
BufferedWriter f = null;
f = new BufferedWriter(new FileWriter(filename));
for (String user : users) {
f.write(user);
f.newLine();
}
f.close();
}
PreparedStatement prstInsert = con.prepareStatement("INSERT INTO users VALUES (?)");
BufferedReader in = new BufferedReader(new FileReader(filename));
int i = 0;
while (true) {
String s = in.readLine();
if (s == null) { // end of file
log.info("Total imported users: " + i);
break;
}
i++;
int userid = Integer.parseInt(s);
prstInsert.setInt(1, userid);
if (i != 0 && Math.round((double) i / 100) == ((double) i / 100)) {
log.info("Imported users: " + i);
}
prstInsert.executeUpdate();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}