Ninja Coding
Ninja Coding

Reputation: 1404

Ormlite: foreignAutoCreate insert if not exists

i noticed that foreignAutoCreate crash when a related data already exists, throwing something like this:

E/SQLiteLog﹕ (2067) abort at 20 in [INSERT INTO `Group` (... etc,`id` ) VALUES (?,?,?)]:
    UNIQUE constraint failed: Group.id

but i have a list, example:

List<User> lstUsers = //values

im inserting values with a loop "for" with createOrUpdate:

for(...) {
   dao.createOrUpdate(user);
}

and User has related data with Group by example:

@DatabaseField(canBeNull = true, foreign = true, foreignAutoCreate = true,
      foreignAutoRefresh = true)
private Group group;

When i have a repeated Group id value the operation fails:

lstUsers.get(0).getGroup().getId(); // group id = 1 <-- foreign insert
lstUsers.get(1).getGroup().getId(); // group id = 1 <-- crash
lstUsers.get(3).getGroup().getId(); // group id = 1 <-- crashed already
lstUsers.get(3).getGroup().getId(); // group id = 2 <-- crashed already
... etc.

i need to insert a group or groups that is not reppeated (insert only 1 time) automatically with foreignAutoCreate no manually.

lstUsers.get(0).getGroup().getId(); // group id = 1 <-- foreign insert
lstUsers.get(1).getGroup().getId(); // group id = 1 <-- foreign exists, skip
lstUsers.get(3).getGroup().getId(); // group id = 1 <-- foreign exists, skip
lstUsers.get(3).getGroup().getId(); // group id = 2 <-- foreign insert

there is a way to do this??

UPDATE 1:

Try with this test please:

public void poblatingUsersAndGroupsList(){
    List<User> lstUsers = new ArrayList<>();
    Group group1 = new Group();
    // this group doesn't exists in database
    group1.setId(1); // should be inserted by ForeignAutoCreate
    lstUsers.add(new User("user1",group1));
    lstUsers.add(new User("user2",group1));
    lstUsers.add(new User("user3",group1));

    Group group2 = new Group();
    group1.setId(2);
    // this group doesn't exists in database
    group1.setId(1); // should be inserted by ForeignAutoCreate
    lstUsers.add(new User("user4",group1));
    lstUsers.add(new User("user5",group2));
    lstUsers.add(new User("user6",group2));

    createUsersInGroup(lstUsers);
}

public void createUsers(List<User> lstUsers){
    for(User user : lstUsers){
        // here is the error
        // group1 inserted the 1st time 
        // the 2nd, 3rd, n times are throwing error
        // same for group2
        dao.createOrUpdate(user);
    }
}

foreignAutoCreate should work like this code, so we can avoid this block of code:

public void createUsers(List<User> lstUsers){
    for(User user : lstUsers){
        // (innecesary) calling or instantiating the groupDao 
        // (innecesary) check if not exists
        groupDao.createIfNotExists(user.getGroup());
        dao.createOrUpdate(user);
    }
}

Upvotes: 0

Views: 492

Answers (1)

Gray
Gray

Reputation: 116908

This is an old question and I assume you moved on. I was not able to reproduce this however. I've expanded the test cases with multiple inserts using dao.createOrUpdate(...). See the ForeignObjectTest unit test code.

One thing that I wonder about is that when you are creating a User with an assocaited Group, the Group must have been created already so that it has an id. Is that possibly the problem?

Group group = new Group();
// need to do this first to have group get an id
groupDao.create(group);
User user = new User();
user.setGroup(group);
for(...) {
   dao.createOrUpdate(user);
}

Upvotes: 0

Related Questions