6

I'm trying to play around and understand the Room persistence library of Android. So far I got how to insert things and query them, but now I'm trying to have 2 constructors in order to not insert a field if I dont want to.

Something like this:

    public ImageData(int id, String name, String title, String description, int locationId) {

 .....

      public ImageData(int id, String name, String title, String description) {

In some cases I won't have a location and therefore I don't want to insert anything in that int Location column. Is this the right way to achieve it(apparently not because I get errors)?

Error:(38, 12) error: Room cannot pick a constructor since multiple constructors are suitable. Try to annotate unwanted constructors with @Ignore.

Please let me know if you need more information.

Edit:

@Entity(primaryKeys = {"id", "name"},
        foreignKeys = @ForeignKey(entity = Location.class,
        parentColumns = "id",
        childColumns = "location_id",
        onDelete=CASCADE))
public class ImageData {

    @NonNull
    public int id;
    @NonNull
    public String name;

    public String title;
    public String description;
    public String time;

    @ColumnInfo(name = "location_id")
    @Nullable
    public int locationId;


    public ImageData(int id, String name, String title, String description, int locationId) {
        this.id = id;
        this.name = name;
        this.title = title;
        this.description = description;
        this.locationId = locationId;
    }

    public ImageData(int id, String name, String title, String description) {
        this.id = id;
        this.name = name;
        this.title = title;
        this.description = description;
    }


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getName() {
        return title;
    }

    public void setName(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getLocationId() {
        return locationId;
    }

    public void setLocationId(int locationId) {
        this.locationId = locationId;
    }

}

@Entity
public class Location {

        @PrimaryKey(autoGenerate = true)
        public int id;

        public double latitude;
        public double longitude;

        public Location(double latitude, double longitude) {
                this.latitude= latitude;
                this.longitude= longitude;
        }

        public int getId() {
                return this.id;
        }
}
Bogdan Daniel
  • 2,689
  • 11
  • 43
  • 76

4 Answers4

2

Method 1

Try using an if statement to determine where location field is empty or has data in it and use the constructors based on the result.


Edit:

So basically, Room database only allows you to use one constructor at a time, so in your case, just delete the one constructor which does not have location in it. This will get rid of the error, but when you are adding a new row to database use this when you do not want to pass in the location id.

database.objectDAO.addObject(id, name, title, description, null);
hysabone.com
  • 2,959
  • 2
  • 15
  • 26
  • Method 1 cannot work with only null put in there. I don't get method 2. I'll still get the same error for having 2 constructors. – Bogdan Daniel Jan 04 '18 at 04:34
2

Try using default value annotation for the entity fields that can have null value such as: @ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")

Xokarca
  • 31
  • 4
1

You should do the following changes, you can use @ignore annotation.

  public ImageData(int id, String name, String title, String description, int locationId) {
        this.id = id;
        this.name = name;
        this.title = title;
        this.description = description;
        this.locationId = locationId;
    }

    @Ignore
    public ImageData(int id, String name, String title, String description) {
        this.id = id;
        this.name = name;
        this.title = title;
        this.description = description;
    }
lib4backer
  • 3,337
  • 3
  • 18
  • 16
  • Still get the same error if I keep both constructors – Bogdan Daniel Jan 04 '18 at 04:33
  • I edited my answer , pls check if incase that might be the issue. – lib4backer Jan 04 '18 at 04:50
  • I think it does, I'll let you know after I get why I get a "Foreign key constraint failed" error. – Bogdan Daniel Jan 04 '18 at 12:08
  • Solution was for two constructor, if that's solved pls accept the answer, so it will help others, foreign key issue because locaiin_id cannot be null as there is a foreign key reference . – lib4backer Jan 04 '18 at 12:15
  • Very well. But I will not be sure it's working only after I m able to test inserting an image, which can happen after I insert a Location item. For some reason, I cannot insert anything. – Bogdan Daniel Jan 04 '18 at 12:41
  • This is because If you read my last comment in your question. That will solve your problem I believe. Here it is" In your case actually Location should be child class and ImageData should be parent class rite? As location wont be present with each and every data. The table you have created viceversa." – lib4backer Jan 04 '18 at 12:42
  • That would be the case if the location got inserted in the first place. `Location location = new Location(imageLocation[0], imageLocation[1]); db.imageDao().insertLocation(location);` doesn't insert anything. – Bogdan Daniel Jan 04 '18 at 12:44
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/162514/discussion-between-lib4-and-bogdan-daniel). – lib4backer Jan 04 '18 at 12:50
  • @BogdanDaniel I am having a similar issue to you, did the solution lib4 came up with work for you? – Brian Mar 21 '19 at 17:27
0

Use the Integer class instead of int.
Same for Boolean instead of boolean and so on

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
deni5n
  • 97
  • 1
  • 10
  • 3
    how is this related to the question? – Skandix Apr 18 '19 at 09:53
  • 1
    I had a similar, yet related problem where all my fields were non-nullable by default but I needed some of them nullable. Changing from primitive types to object types solved the problem because primitive types can't have null references. See https://stackoverflow.com/a/49175873/8078494 for more explanation. – ecotner Jan 26 '20 at 20:47