Skip to content

Example for custom type seems to be backwards in implementation #533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ChickenF622 opened this issue Apr 29, 2023 · 4 comments
Closed

Example for custom type seems to be backwards in implementation #533

ChickenF622 opened this issue Apr 29, 2023 · 4 comments
Labels
more info required Needs more info to become actionable. Auto-closed if no response. question How to do something/general question

Comments

@ChickenF622
Copy link

Was running into an issue where the start hour and minute were not getting saved to the database. According to the example it seems that the non-database friendly value can be property as long as it's marked as @transient, and getters/setters can be used to break it down into a more database friend value (in this case int). If I were to reverse the implementation where the minute and hour values are just values and the startTime TimeOfDay is provided via getter/setters the values are stored properly.

Link to documentation: https://docs.objectbox.io/advanced/custom-types#convert-annotation-and-property-converter

Example of code that works

@Entity
class Event {
  int id = 0;
  int startTimeHour = 0;
  int startTimeMinute = 0;


  @Transient()
  TimeOfDay get startTime {
    return TimeOfDay(hour: startTimeHour, minute: startTimeMinute);
  }

  set startTime(TimeOfDay startTime) {
    startTimeHour = startTime.hour;
    startTimeMinute = startTime.minute;
  }
}

Example of code that doesn't work, and follows the pattern in the example

@Entity
class Event {
  int id = 0;
  @Transient
  TimeOfDay startTime;
  Event({required this.startTime});

  int get startTimeHour {
    return startTime?.hour;
  }

  set startTimeHour(int hour) {
    startTime = startTime.replacing(hour: hour);
  }

  int get startTimeMinute {
    return startTime.minute;
  }

  set startTimeMinute(int minute) {
    startTime = startTime.replacing(minute: minute);
  }
}
@greenrobot-team
Copy link
Member

greenrobot-team commented May 2, 2023

The first example you have given actually only works because currently annotations are not recognized on getters and setters (see #392). It also prints a warning when running flutter pub run build_runner build --delete-conflicting-outputs:

[WARNING] objectbox_generator:resolver on lib/model.dart:
  Skipping property 'startTime': type 'TimeOfDay' not supported, consider creating a relation for @Entity types (https://docs.objectbox.io/relations), or replace with getter/setter converting to a supported type (https://docs.objectbox.io/advanced/custom-types).

What is broken with the second example is the initialization. ObjectBox requires a constructor that supplies all stored properties so it can restore an object. E.g. this works:

@Entity()
class Event {
  int id = 0;

  @Transient()
  TimeOfDay startTime = const TimeOfDay(hour: 0, minute: 0);

  int get startTimeHour {
    return startTime.hour;
  }

  set startTimeHour(int hour) {
    startTime = startTime.replacing(hour: hour);
  }

  int get startTimeMinute {
    return startTime.minute;
  }

  set startTimeMinute(int minute) {
    startTime = startTime.replacing(minute: minute);
  }

  Event(this.id, int startTimeHour, int startTimeMinute) {
    this.startTimeHour = startTimeHour;
    this.startTimeMinute = startTimeMinute;
  }
}

Let me know if you have more questions. Otherwise close this issue (it will auto-close if no response in 2 weeks).

@greenrobot-team greenrobot-team added more info required Needs more info to become actionable. Auto-closed if no response. question How to do something/general question labels May 2, 2023
@ChickenF622
Copy link
Author

I may be missing something, but the example here: https://docs.objectbox.io/advanced/custom-types#convert-annotation-and-property-converter. Doesn't provide a constructor like that, so I think the example should be updated. I do see the note about the constructor here: https://docs.objectbox.io/entity-annotations#objectbox-database-persistence-with-entity-annotations, but it is on an entirely separate page. I think it would be helpful if the example reflected that. If you don't agree I'll close the issue. Thanks for taking a look at this.

@github-actions github-actions bot removed the more info required Needs more info to become actionable. Auto-closed if no response. label May 3, 2023
@greenrobot-team
Copy link
Member

Doesn't provide a constructor like that

Ah sorry. This is the other possibility: make fields nullable (Role? role;, int? get dbRole and set dbRole(int? value) in this case) so they do not require initialization. ObjectBox will then set the field directly to construct a new object.

@greenrobot-team greenrobot-team added the more info required Needs more info to become actionable. Auto-closed if no response. label May 3, 2023
@github-actions
Copy link

Without additional information, we are unfortunately not sure how to resolve this issue. Therefore this issue has been automatically closed. Feel free to comment with additional details and we can re-open this issue.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale May 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
more info required Needs more info to become actionable. Auto-closed if no response. question How to do something/general question
Projects
None yet
Development

No branches or pull requests

2 participants