Closed YSDC closed 8 years ago
@YSDC do you have foreign key constraints turned on? @Database(foreignKeysSupported = true)
?
Yes sure:
@Database(name = DatabaseHelper.DBNAME, version = BuildConfig.DATABASE_VERSION, foreignKeysSupported = true)
public class DatabaseHelper {
Let me know if you need any more information to help me, it's a bit blocking this cascade, and I don't want to do an ugly loop to remove manually all items :(
What i tried already:
Media media
by
ForeignKeyContainer<Media> media;
but no positive result...BTW for the ForeignKeyContainer
you should add to the documentation that it's necessary to add the @ContainerAdapter
annotation to make it works
Some other information: I have enable low level log with FlowLog and have this message.
FlowLog﹕ Foreign Keys supported. Enabling foreign key features.
meaning that's it's supported.
I have also the right create sql command in my adapter
@Override
public String getCreationQuery() {
return String.format("CREATE TABLE IF NOT EXISTS `NewsMedia`(`id` INTEGER PRIMARY KEY AUTOINCREMENT, `news` TEXT, `media` INTEGER, `main` INTEGER, UNIQUE (`news`, `media`) ON CONFLICT FAIL, FOREIGN KEY(`news`) REFERENCES `%1s` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`media`) REFERENCES `%1s` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE );",FlowManager.getTableName(*******.News.class), FlowManager.getTableName(******.Media.class));
}
The **\ are only here to hide package name
What version of Android is this running on?
Thanks for your answer. I tried on different phones that were 4.x I will give you a more precise version in the next 24 hours. I have created a sample project with the minimum of classes, I can send it to you if you want
Hey, can you please update if you solved this issue?
This should work in other way, if you do new Delete().from(Media.class).query(); then related MyClass records will be deleted.
After several failed attempts using foreign keys I found the way to implement One-To-One relationship using OneToMany annotation.
User.java
@Table(tableName = "Users", databaseName = "mydb")
@ModelContainer
public class User extends BaseModel {
@Column(name = "id")
@PrimaryKey(autoincrement = true)
private long id;
@Expose
@Column(name = "userId")
@NotNull
@Unique(onUniqueConflict = ConflictAction.REPLACE)
private String userId;
@Expose
// should be non-private due to the DBFlow compiler limitation
/*private*/ UserProfile userProfile;
@OneToMany(methods = {OneToMany.Method.ALL})
public UserProfile getUserProfile() {
if (userProfile == null) {
userProfile = new Select().from(UserProfile.class)
.where("userId=?", userId).querySingle();
}
return userProfile;
}
@Override
public void save() {
if (userProfile != null) {
userProfile.setUserId(userId);
}
super.save();
}
}
UserProfile.java
@Table(tableName = "UserProfiles", databaseName = "mydb")
public class UserProfile extends BaseModel {
@Column(name = "id")
@PrimaryKey(autoincrement = true)
private long id;
@Expose
@Column(name = "firstName")
private String firstName;
@Column(name = "userId")
@NotNull
@Unique(onUniqueConflict = ConflictAction.REPLACE)
private String userId;
}
OneToManyValidator does not validate the filed type have to be a List. So that became possibly to user this annotation for non List variable :)
Example use:
// create
UserProfile profile = new UserProfile();
User user = new User();
user.setUserId("133456789");
user.setUserProfile(profile);
user.save(); // saves also a userProfile
// load
User user = new Select().from(User.class).querySingle();
user.getUserProfile(); // not null, loaded from DB
// modify
user.getUserProfile().setFirstName("john");
user.save(); // saves also a userProfile
// delete
user.delete(); // deletes user and associated userProfile
@agrosner Is it possible by default to use gettters and setters to get access to private memebrs in generated code? @agrosner The provided "OneToOne" solution still uses *ModelListTransaction (see OneToManyDefinition) to modify sub-models. Maybe there is a reason to add OneToOne annotation?
+1 OneToOne annotation
I was wondering what's currently the preferred way of making a OneToOne-Relation work. I'm struggling with getting it to work when I'm following the current Document of DBFlow 4.0.4.
I try to use the "onDelete" with ForeignKeyAction.CASCADE but without success. I have the following annotation in a class that we will call MyClass:
But when i do this
The Media is not deleted. Any idea why?