After Reading the doc's Relations pages, I can use a many to many relation like this:
#Entity
public class Product {
#Id private Long id;
#ToMany
#JoinEntity(
entity = JoinProductsWithOrders.class,
sourceProperty = "productId",
targetProperty = "orderId"
)
private List<Order> ordersWithThisProduct;
}
#Entity
public class JoinProductsWithOrders {
#Id private Long id;
private Long productId;
private Long orderId;
}
#Entity
public class Order {
#Id private Long id;
}
Now, with this code, can I have a bi-directionel relations and access from an Order the list of Products associated with it?
Or should I add a Product List in the Order class too? Something like this:
...
#Entity
public class Order {
#Id private Long id;
#ToMany //I don't know if this is corect btw.
private List<Product> productsForThisOrder;
}
This is how you should do it:
#Entity
public class Order {
#Id private Long id;
#ToMany
#JoinEntity(
entity = JoinProductsWithOrders.class,
sourceProperty = "orderId",
targetProperty = "productId"
)
private List<Product> productsForThisOrder;
}
Related
How can I join two classes in ObjectBox which have one two many relationship?
I have two tables as following:
#Entity
public class Animal {
#Id(assignable = true)
public long id;
private String name;
private boolean flying;
private boolean swimming;
private boolean walking;
private ToOne<Zoo> zoo;
.../*setters and getters*/
}
and:
#Entity
public class Zoo {
#Id
public long id;
private String name;
// a Zoo can have many Animals
#Backlink
ToMany<Animal> animals;
.../*setters and getters*/
}
How can I implement Join operation?
Since version 2.0.0 you can do something like:
val builder = box.query().equal(Zoo_.name, "The Big Zoo")
builder.link(Zoo_.animals).equal(Animal_.flying, true)
val flyingAnimals = builder.build().find()
This is called "links" and there is documentation on it with an additional example.
I am quite familiar with these kind of thing on Spring JPA but I can not make it work on Android. I post my code below so you can understand the question better. I have two classes and a third class that needs to contain objects of class 1 and 2. I know that the code for the third class is not correct, since Room does not support object references like that. If I save just the id-s of the objects as foreign keys I am not able to query after the results.
There must be some kind of nice solution for this problem. Thank you.
#Entity(tableName = "soup")
public class Soup {
#PrimaryKey(autoGenerate = true)
private long id;
private String name;
// getter and setters
}
#Entity(tableName = "main_course")
public class MainCourse {
#PrimaryKey(autoGenerate = true)
private long id;
private String name;
// getter and setters
}
#Entity(tableName = "menu")
public class Menu {
#PrimaryKey(autoGenerate = true)
private long id;
private Soup soupOptionOne;
private Soup soupOptionTwo;
private Soup soupOptionThree;
private MainCourse courseOptionOne;
private MainCourse courseOptionTwo;
private MainCourse courseOptionThree;
}
I am having a hard time getting a list item into room. the list item is called measurements and its of type Measurement. the list item has no primarykey that would be related to the database.
but i have no problem adding the same primary key for the ProductModel if necessary.
Here is what i have so far:
#Entity(tableName = TABLE_NAME)
public class ProductModel {
public static final String TABLE_NAME = "product";
#PrimaryKey
private int idProduct;
private int idCategoryDefault;
#Relation(parentColumn = "idProduct", entityColumn = "idProduct", entity = SortedAttribute.class)
private List<SortedAttribute> sortedAttributes = null;
}
#Entity
public class SortedAttribute {
#PrimaryKey
private int idProduct;
private String reference;
#Embedded
private List<Measurement> measurements = null; //****how do i get this into room ? its a LIST of measurements, not a measurement so calling Embedded i think wont work as it cant flatten it****/
}
public class Measurement {
private String value;
private String valueCm;
public Measurement() {
}
}
Embedded annotation can be used on a POJO or Entity only, not for a List. So, Room can not automatically flatten your list in this case.
You can use TypeConverter to convert List<Measurement> into String(in JSON format) and vise versa. You can use any JSON parser library to support it. For example, I use Gson as following.
public class ProductTypeConverters {
#TypeConverter
public static List<Measurement> stringToMeasurements(String json) {
Gson gson = new Gson();
Type type = new TypeToken<List<Measurement>>() {}.getType();
List<Measurement> measurements = gson.fromJson(json, type);
return measurements;
}
#TypeConverter
public static String measurementsToString(List<Measurement> list) {
Gson gson = new Gson();
Type type = new TypeToken<List<Measurement>>() {}.getType();
String json = gson.toJson(list, type);
return json;
}
}
#Entity
#TypeConverters(ProductTypeConverter.class)
public class SortedAttribute {
#PrimaryKey
private int idProduct;
private String reference;
private List<Measurement> measurements = null;
}
EDIT: Use a type converter
#Relation is what you are looking for.
https://developer.android.com/reference/android/arch/persistence/room/Relation.html
From the Room docs:
#Entity
public class Pet {
# PrimaryKey
int petId;
String name;
}
public class UserNameAndAllPets {
public int userId;
public String name;
#Relation(parentColumn = "petId", entityColumn = "userId")
public List<Pet> pets;
}
#Dao
public interface UserPetDao {
#Query("SELECT petId, name from User")
public List<UserNameAndAllPets> loadUserAndPets();
}
Note: Upon further research, Room does not quite support lists of objects that are INSIDE objects. I (and others) have opted to handle the lists separately. Room can handle lists of objects just fine as long as they aren't within an object; so as long as your items inside the list are related to your overall object you can recover the list.
So, you would actually #Ignore the list and just handle it in your Dao abstract class. I could not find the SO post's I found earlier that portray this.
How can i create one-to-many relation with the table itself in ormlite? I have a class that holds collection of itself. I don't know how to map this class.
#DatabaseTable(tableName = "USER")
public class User {
#DatabaseField(generatedId = true)
private long id;
#DatabaseField
private String username;
#ForeignCollectionField
private ForeignCollection<User> friends;
...
Thanks in advance.
I have a class that holds collection of itself. I don't know how to map this class.
I think the best way would be to define a UserFriend entity that has a reference to the owner User, friend User, and an id. Something like:
#DatabaseTable(tableName = "USERFRIEND")
public class UserFriend {
#DatabaseField(generatedId = true)
private long id;
// corresponds to the user who has the friend
#DatabaseField(foreign = true)
private User user;
// corresponds to the friend of the user
#DatabaseField(foreign = true)
private User friend;
...
Then your foreign collection becomes:
#ForeignCollectionField(foreignFieldName = 'user')
private ForeignCollection<UserFriend> friends;
Notice the foreignFieldName which has to point to the user so the user's friends can be found.
I am using ActiveAndroid and have two models:
#Table(name = "Topics")
public class Topic extends Model {
#Column(name = "Name") String name;
#SerializedName("id")
#Column(index = true,
unique = true,
onUniqueConflict = Column.ConflictAction.REPLACE) public long topic_id;
#Column(name = "Counts",
onUpdate = Column.ForeignKeyAction.CASCADE,
onDelete = Column.ForeignKeyAction.CASCADE) Counts counts;
}
and
#Table(name = "Counts")
public class Counts extends Model {
#Column(name = "Users") int users;
}
Constructors have been excluded for brevity.
Now, when i save Topic, I expect the Counts to be saved. But it does not.
I am using gson to create the models from json. Any reason why counts are not being loaded?
First you have to call count.save() then you can call topic.save(). ActiveAndroid needs the id to get the reference and that happen when you save it.