Querys and foreign keys

1,670 views
Skip to first unread message

Federico Vidueiro

unread,
Oct 12, 2010, 7:12:42 PM10/12/10
to ormlit...@googlegroups.com
Hello I'm trying ORMLite on Android and I think is pretty good.
I need some help with querys and froreign key.
I have the classes:

public class Photo {
    @DatabaseField(generatedId = true)
    int id;

    @DatabaseField
    String description;

    @DatabaseField(canBeNull = true, foreign = true)
    Album album;
   
    public Photo(){
        //
    }
}


public class Album {
    @DatabaseField(generatedId = true)
    int id;

    @DatabaseField
    String nombre;
   
    Album() {
        // needed by ormlite
    }
   
    public Album (String nombre){
        this.nombre = nombre;
    }
   
    @Override
    public String toString() {
        return nombre;
    }
}


the album is the foreign key in photo class.

I need to build a query to get all the photos from given album, something like this:

    public List<Photo> getPhotos(Album album){
            QueryBuilder <Photo, Integer> queryBuilder = getHelper().getPhotoDao().queryBuilder();
            queryBuilder.where().eq("album", album); // Here is the problem
            return getHelper().query(queryBuilder.prepare());
    }

Thanks in advance,
Federico

Kevin Galligan

unread,
Oct 12, 2010, 7:36:03 PM10/12/10
to ormlit...@googlegroups.com
Good question. I meant to ask Gray that myself. I has this same
issue, and I believe the error you got was the column wasn't in the
db? I'm in crisis mode with my apps right now, so i didn't take any
time to figure it out. I just found the name of the column in the db
and queried that directly.

Most likely, the column is actually called "album_id". So, the line
would look like...

queryBuilder.where().eq("album_id", album.id);

The query *should* understand foreign objects, I think, but there may
be some weirdness involved. In any case, something to discuss. Use
workaround for today.

Its also possible I missed something in the config myself.

-Kevin

Federico Vidueiro

unread,
Oct 12, 2010, 8:11:07 PM10/12/10
to ormlit...@googlegroups.com
Thanks Kevin, I solved by the hard way. Change "Album" attribute from "Photo" to albumId and remove foreign information, managing the relation logic my self.
However it would be great if the framework could handle this.


2010/10/12 Kevin Galligan <kgal...@gmail.com>

Kevin Galligan

unread,
Oct 12, 2010, 8:16:28 PM10/12/10
to ormlit...@googlegroups.com
It does understand it going the other way. If you have a photo, it
will have a reference to the album, although the reference will only
have the id value (you manually have to refresh it).

But I hear you.

-Kevin

Gray Watson

unread,
Oct 12, 2010, 9:26:05 PM10/12/10
to ormlit...@googlegroups.com
On Oct 12, 2010, at 7:12 PM, Federico Vidueiro wrote:

> @DatabaseField(canBeNull = true, foreign = true)
> Album album;
>

> public List<Photo> getPhotos(Album album){
> QueryBuilder <Photo, Integer> queryBuilder = getHelper().getPhotoDao().queryBuilder();
> queryBuilder.where().eq("album", album); // Here is the problem
> return getHelper().query(queryBuilder.prepare());
> }

Your query is fine except the name of the field is not "album" -- it is "album_id". It seemed wrong to take the field name when we weren't storing the field in the table. The recommended way to do this is:

public class Photo {
public final static String ALBUM_FIELD_NAME = "album";
...
@DatabaseField(canBeNull = true, foreign = true, columnName = ALBUM_FIELD_NAME)
Album album;
}

then:

queryBuilder.where().eq(Photo.ALBUM_FIELD_NAME, album);

I think this is covered in the manual but I will add additional information about id column names. I could also see if the field is unknown then it will look for the field name instead of the column name -- but I might spit a warning message out.

gray

Gray Watson

unread,
Oct 12, 2010, 11:16:54 PM10/12/10
to ormlit...@googlegroups.com
I've improved the messaging:

java.lang.IllegalArgumentException: You should use columnName 'album_id' for table foo instead of fieldName 'album'

Hope this helps. I'd rather not do automatic conversions or anything like that.
gray

Federico Vidueiro

unread,
Oct 13, 2010, 9:13:20 AM10/13/10
to ormlit...@googlegroups.com
Thanks Gray, I'll change it.

Adam Wong

unread,
Mar 28, 2012, 4:18:44 PM3/28/12
to ormlit...@googlegroups.com
Greetings! This was the only place google could find a reference to the error, "java.lang.IllegalArgumentException: You should use columnName 'album_id' for table foo instead of fieldName 'album'" which I'm getting intermittently. Sometimes my android app throws the error, sometimes it does not- I can't even reproduce the error consistently. . Here some code:

surgeons = surgeonManager.getSurgeons(0, "lastName", true, "id", "firstName", "lastName", "address1");

////////////////////

public List<Surgeon> getSurgeons(Integer maxRows, String orderByColumnName, boolean ascending, String... columns) throws SQLException {
QueryBuilder<Surgeon, Integer> builder = surgeonDao.queryBuilder();
if (!StringUtil.isEmpty(columns[0])) {
builder.selectColumns(columns); //The error is thrown here 
}
if (orderByColumnName != null) {
builder.orderBy(orderByColumnName, ascending);
}
if (maxRows > 0) {
builder.limit(maxRows);
}
return surgeonDao.query(builder.prepare());
}

And the stack trace:

03-28 12:59:23.740: E/AndroidRuntime(2833): FATAL EXCEPTION: AsyncTask #4
03-28 12:59:23.740: E/AndroidRuntime(2833): java.lang.RuntimeException: An error occured while executing doInBackground()
03-28 12:59:23.740: E/AndroidRuntime(2833): at android.os.AsyncTask$3.done(AsyncTask.java:278)
03-28 12:59:23.740: E/AndroidRuntime(2833): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
03-28 12:59:23.740: E/AndroidRuntime(2833): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
03-28 12:59:23.740: E/AndroidRuntime(2833): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
03-28 12:59:23.740: E/AndroidRuntime(2833): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
03-28 12:59:23.740: E/AndroidRuntime(2833): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
03-28 12:59:23.740: E/AndroidRuntime(2833): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
03-28 12:59:23.740: E/AndroidRuntime(2833): at java.lang.Thread.run(Thread.java:856)
03-28 12:59:23.740: E/AndroidRuntime(2833): Caused by: java.lang.IllegalArgumentException: You should use columnName 'id' for table Surgeon instead of fieldName 'id'
03-28 12:59:23.740: E/AndroidRuntime(2833): at com.j256.ormlite.table.TableInfo.getFieldTypeByColumnName(TableInfo.java:115)
03-28 12:59:23.740: E/AndroidRuntime(2833): at com.j256.ormlite.stmt.StatementBuilder.verifyColumnName(StatementBuilder.java:155)
03-28 12:59:23.740: E/AndroidRuntime(2833): at com.j256.ormlite.stmt.QueryBuilder.addSelectColumnToList(QueryBuilder.java:180)
03-28 12:59:23.740: E/AndroidRuntime(2833): at com.j256.ormlite.stmt.QueryBuilder.selectColumns(QueryBuilder.java:82)
03-28 12:59:23.740: E/AndroidRuntime(2833): at com.mobileworkforce.andalucia.domain.ormlite.SurgeonManagerImpl.getSurgeons(SurgeonManagerImpl.java:106)
03-28 12:59:23.740: E/AndroidRuntime(2833): at com.mobileworkforce.andalucia.activities.SurgeonsActivity$SurgeonFetchTask.doInBackground(SurgeonsActivity.java:351)
03-28 12:59:23.740: E/AndroidRuntime(2833): at com.mobileworkforce.andalucia.activities.SurgeonsActivity$SurgeonFetchTask.doInBackground(SurgeonsActivity.java:1)
03-28 12:59:23.740: E/AndroidRuntime(2833): at android.os.AsyncTask$2.call(AsyncTask.java:264)
03-28 12:59:23.740: E/AndroidRuntime(2833): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
03-28 12:59:23.740: E/AndroidRuntime(2833): ... 4 more

Do you guys have any idea whats going on? Thanks in advance.

Gray

unread,
Apr 13, 2012, 3:17:18 PM4/13/12
to ormlit...@googlegroups.com
On Wednesday, March 28, 2012 4:18:44 PM UTC-4, Adam Wong wrote:
Greetings! This was the only place google could find a reference to the error, "java.lang.IllegalArgumentException: You should use columnName 'album_id' for table foo instead of fieldName 'album'" which I'm getting intermittently. Sometimes my android app throws the error, sometimes it does not- I can't even reproduce the error consistently. . Here some code:
 
03-28 12:59:23.740: E/AndroidRuntime(2833): Caused by: java.lang.IllegalArgumentException: You should use columnName 'id' for table Surgeon instead of fieldName 'id'

Wow is that ugly.  That's a really bad error trying to help you out.  I'll fix the error message to be smarter.

Basically what it should be saying is that there is no such field name in your table named 'id'.  Did you maybe define a columnName and then not use it in your schema?  Or maybe does the database not have id in it?

gray
 

Gray Watson

unread,
Apr 13, 2012, 4:42:14 PM4/13/12
to ormlit...@googlegroups.com
On Mar 28, 2012, at 4:18 PM, Adam Wong wrote:

> 03-28 12:59:23.740: E/AndroidRuntime(2833): Caused by: java.lang.IllegalArgumentException: You should use columnName 'id' for table Surgeon instead of fieldName 'id'

Wait, what? Cancel that. I don't understand this at all. You are searching for field 'id'. That you get to this point means that it did not match the column names in the map.

Any chance this is a thread race condition? Could the table be in the process of being initialized when this happened?
gray

Reply all
Reply to author
Forward
0 new messages