1

I new to Room, and @Relation isn't clear for me. If I understand correctly, I have entities e.g. (RSS)ChannelEntity, and channel has items named ItemEntity. These are classes wiht @Entity annotation. I also have a POJO to "connect" my entites. I mean I've to write a POJO like this:

public class Channel { 

   @Embedded
   private ChannelEntity channel;

// Link is the primary key in ChannelyEntity
   @Relation (parentColumn = "link", entityColumn = "channel_link")
   private ArrayList<ItemEntity> items;

// Getters and Setters are here
}

Than I've to write a dao interface where I can get Channel (not ChannelEntity) like this:

public interface ChannelDao {

    @Query("SELECT * FROM channels WHERE link = :link LIMIT 1")
    Channel getChannelById(String link);

    @Query("SELECT * FROM channels")
    ArrayList<Channel> getAllChannels();
}

With these Entities, DAOs and POJOs I can get Channel objects which contain a list of Items with the corresponding link (id). Is that right?

My other is question about the rest CRUD. E.g. if I'd like to save a new channel can I add this statement to my ChannelDao?

@Insert(onConflict = OnConflictStrategy.REPLACE)
void createChannels(Channel... channels);

to delete

@Delete
void deleteChannels(Channel... channels);

and so on. So will it create and delete the ChannelEntities and ItemEntities from the passed Channel object?

user3057944
  • 701
  • 1
  • 8
  • 19
  • Are you asking or have you tried and this doesn’t work? Room Persistence Library is new (and alpha) so not a lot of experienced android users have had time to play with it (given that it’s unlikely to be used in production *yet*), so it’s best to come up with concrete errors, samples in general; it sounds like you’re just trying to get validation, but nobody will have time to test this. So go ahead, try it and then report errors when they happen. And post all your relevant classes, nor just 1/2 of them. – Martin Marconcini Jul 18 '17 at 17:08
  • "can I add this statement to my ChannelDao?" -- AFAIK, no. The idea behind `@Relation`, near as I can tell, is to use it for populating a view model. – CommonsWare Jul 18 '17 at 17:14
  • I haven't used it yet, at first I'd like to find out how can I persistate and read it from db with Room objects that contains list or other objects. If I use @ForeignKey I can get back the object with the list in one query. – user3057944 Jul 18 '17 at 17:33
  • @CommonsWare so you say I have to write daos for these entities and I can use Relation annotation to get the Channel object? – user3057944 Jul 18 '17 at 17:48
  • I am saying that AFAIK `@Relation` is a read-only construct. When you want to save things, AFAIK, you are using entities (or custom SQL in a `@Query`), not a POJO with `@Relation`. – CommonsWare Jul 18 '17 at 19:26
  • Please refer to this SO answer. https://stackoverflow.com/a/44424148 – E-Rock Jul 18 '17 at 21:01

1 Answers1

1

I updated my classes as @CommonsWare adviced it. Now I have entity classes with @Embedded object:

    @Entity (tableName = "channels")
public class ChannelEntity {
    // Required channel elements
    // The name of the channel. It's how people refer to your service.
    private String title;
    // The URL of the HTML website corresponding to the channel
    @PrimaryKey
    private String link;
    //other fileds
    @Embedded
    private TextInputEntity textInputEntity;
    @Embedded
    private ImageEntity imageEntity;
    //getters and setters
}

One of the embedded classes:

// Specifies a text input box displayed with the channel.
// Embedded in ChannelEntity
public class TextInputEntity {
    // Required elements
    // The label of the Submit button in the text input area.
    private String title;
    // Explains the text input aera.
    private String description;
    // The name of the text object int hte text input area.
    private String name;
    // The URL of the CGI script that processes the text input request
    private String link;
    @ColumnInfo (name = "channel_link")
    private String channelLink;
}

I've wrote daos for all classes have @Entity annotation(I called embedded classes entity even they aren't, but I'd have model classes for views and I don't want to mix up them later).

I mapped relations like this:

// All items are optional, but at least one of title or description must be presented.
@Entity (tableName = "items"
        , foreignKeys = @ForeignKey (entity = Channel.class
        , parentColumns = "link"
        , childColumns = "channel_link"))
public class ItemEntity {
    @PrimaryKey (autoGenerate = true)
    private int id;
    // Title of the item
    private String title;
    // Other fileds
    @ColumnInfo (name = "channel_link")
    private String channelLink;
    // Getters and setters

And when I want to get a Channel with the list of items I get it like this:

public class Channel {
    @Embedded
    private ChannelEntity channel;
    @Relation (parentColumn = "link", entityColumn = "channel_link")
    private ArrayList<ItemEntity> items;
    @Relation (parentColumn = "link", entityColumn = "channel_link")
    private ArrayList<SkipDayEntity> skipDays;
    @Relation (parentColumn = "link", entityColumn = "channel_link")
    private ArrayList<SkipHourEntity> skipHours;
//Setters and getters
}

And this is the dao for Channel:

@Dao
public interface ChannelDao {
    @Insert (onConflict = OnConflictStrategy.REPLACE)
    void insertChannel(ChannelEntity channel);

    @Update
    void updateChannel(ChannelEntity channel);

    @Delete
    void deleteChannel(ChannelEntity channel);

    @Query ("SELECT * FROM channles WHERE link = :link LIMIT 1")
    Channel getChannelByLink(String link);

    @Query ("SELECT * FROM channels")
    LiveData<ArrayList<Channel>> getAllChannels();
}
user3057944
  • 701
  • 1
  • 8
  • 19