objectbox / objectbox-dart

Flutter database for super-fast Dart object persistence
https://docs.objectbox.io/getting-started
Apache License 2.0
927 stars 115 forks source link

Freezed entities don't work well with objectbox_generator #424

Open atarana opened 1 year ago

atarana commented 1 year ago

ObjectBox Generator doesn't generate objectbox-model.json and objectbox.g.dart with freezed entities.

As a workaround I found that using flutter pub run build_runner watch --delete-conflicting-outputs and changing just one of the entity's @Id(assignable: ) from true to false and vice-versa does the trick sometimes.

Basic info (please complete the following information):

Additionally, you can choose to provide more details, e.g. the output of:

[✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1) • Android SDK at /Users/alextarana/Library/Android/sdk • Platform android-31, build-tools 32.1.0-rc1 • ANDROID_SDK_ROOT = /Users/alextarana/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.1) • Xcode at /Applications/Xcode.app/Contents/Developer • CocoaPods version 1.11.2

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)

[✓] VS Code (version 1.67.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.40.0

[✓] Connected device (2 available) • macOS (desktop) • macos • darwin-x64 • macOS 12.0.1 21A559 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 101.0.4951.64 ! Error: Unable to prepare Alex iPhone for development. (code -1)

[✓] HTTP Host Availability • All required HTTP hosts are available

• No issues found!


### Steps to reproduce

1. Create a flutter project and import the code below
2. Try to use `flutter pub run build_runner build --delete-conflicting-outputs`
3. Nothing happens

### Expected behavior

Should generate `objectbox-model.json` and `objectbox.g.json`.

### Code

import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:objectbox/objectbox.dart';

part 'otodbs.freezed.dart';

@freezed class BrandOtoDb with _$BrandOtoDb { @Entity(realClass: BrandOtoDb) factory BrandOtoDb({ @Id(assignable: true) required int? id, @Unique(onConflict: ConflictStrategy.replace) required String name, }) = _BrandOtoDb; }

@freezed class InfoOtoDb with _$InfoOtoDb { @Entity(realClass: InfoOtoDb) factory InfoOtoDb({ @Id(assignable: false) required int? id, required String sentricId, required String name, required String title, required String subtitle, required String image, }) = _InfoOtoDb; }

@freezed class MediaGalleryOtoDb with _$MediaGalleryOtoDb { @Entity(realClass: MediaGalleryOtoDb) factory MediaGalleryOtoDb({ @Id(assignable: true) required int? id, @Unique() required String url, required bool validated, // required ToOne product, // required ToOne variant, // required ToOne previewVariant, // required ToOne previewProduct, }) = _MediaGalleryOtoDb; }

@freezed class PreviewProductOtoDb with _$PreviewProductOtoDb { @Entity(realClass: PreviewProductOtoDb) const factory PreviewProductOtoDb({ @Id(assignable: true) required int? id, required String? sentricId, required String? parent, required bool validated, required String? option1Name, required String? option2Name, required String? category, required String? brand, required String? customProductBarcode, required String title, required String? description, required String? descriptionValidated, required List barcodes, // @Backlink('previewProduct') required ToMany variants, // @Backlink('previewProduct') required ToMany mediaGallery, required int? quantity, required String ownerShop, @Property(type: PropertyType.date) required DateTime updatedDate, required double? price, required double? priceComparison, }) = _PreviewProductOtoDb; }

@freezed class PreviewVariantOtoDb with _$PreviewVariantOtoDb { @Entity(realClass: PreviewVariantOtoDb) factory PreviewVariantOtoDb({ @Id(assignable: true) required int? id, required String? parent, required String? sentricId, required String? option1Value, required String? option2Value, required List barcodes, required int? imageIndex, required int? quantity, required bool? validated, required double? price, required String? customProductBarcode, required ToOne product, // @Backlink('previewVariant') required ToMany mediaGallery, required double? priceComparison, @Property(type: PropertyType.date) required DateTime updatedDate, }) = _PreviewVariantOtoDb; }

@freezed class ProductOtoDb with _$ProductOtoDb { @Entity(realClass: ProductOtoDb) factory ProductOtoDb({ @Id(assignable: true) required int? id, required String? sentricId, required String? parent, required bool validated, required String? option1Name, required String? option2Name, required String? category, required String? brand, required String? customProductBarcode, required String title, required String? description, required String? descriptionValidated, required List barcodes, // @Backlink('product') required ToMany variants, // @Backlink('product') required ToMany mediaGallery, required int? quantity, required String ownerShop, @Property(type: PropertyType.date) required DateTime updatedDate, required double? price, required double? priceComparison, }) = _ProductOtoDb; }

@freezed class ProductReferenceOtoDb with _$ProductReferenceOtoDb { @Entity(realClass: ProductReferenceOtoDb) factory ProductReferenceOtoDb({ @Id(assignable: true) required int? id, required List barcodes, }) = _ProductReferenceOtoDb; }

@freezed class VariantOtoDb with _$VariantOtoDb { @Entity(realClass: VariantOtoDb) factory VariantOtoDb({ @Id(assignable: true) required int? id, required String? parent, required String? sentricId, required String? option1Value, required String? option2Value, required List barcodes, required int? imageIndex, required int? quantity, required bool? validated, required double? price, required String? customProductBarcode, required ToOne product, // @Backlink('variant') required ToMany mediaGallery, required double? priceComparison, @Property(type: PropertyType.date) required DateTime updatedDate, }) = _VariantOtoDb; }

Here's my `pubspec.yaml`:

environment: sdk: ">=2.14.0 <3.0.0"

dependencies: animated_check: ^1.0.5 animated_text_kit: ^4.2.1 another_flushbar: ^1.10.28 auto_route: ^4.0.1 cached_network_image: ^3.1.0+1 camera: ^0.9.4+10 carousel_slider: ^4.0.0 charcode: ^1.3.1 connectivity_plus: ^2.2.1 crypto: ^3.0.1 cupertino_icons: ^1.0.4 dart_jsonwebtoken: ^2.4.0 dartz: ^0.10.1 dio: ^4.0.6 dio_smart_retry: ^1.2.0 easy_localization: ^3.0.0 encrypt: ^5.0.1 english_words: ^4.0.0 equatable: ^2.0.3 flutter: sdk: flutter flutter_bloc: ^8.0.1 flutter_image_compress: ^1.1.0 flutter_launcher_icons: ^0.9.2 flutter_loggy_dio: ^2.0.0+3 flutter_platform_widgets: ^1.20.0 flutter_secure_storage: ^5.0.2 flutter_svg: ^1.0.3 font_awesome_flutter: ^10.1.0 freezed_annotation: ^2.0.3 get: ^4.6.1 get_it: ^7.2.0 image_cropper: ^2.0.2 image_picker: ^0.8.4+4 injectable: ^1.5.3 intl: ^0.17.0 json_annotation: ^4.4.0 kt_dart: ^0.10.0 local_auth: ^2.0.2 logger: ^1.1.0 loggy: ^2.0.1+1 modal_bottom_sheet: ^2.0.1 objectbox: ^1.5.0 objectbox_flutter_libs: ^1.5.0 path_provider: ^2.0.9 percent_indicator: ^4.0.0 photo_manager: ^2.1.0+1 provider: ^6.0.1 pull_to_refresh: ^2.0.0 qr_mobile_vision: ^3.0.1 reorderables: ^0.5.0 retrofit: ^3.0.1+1 rxdart: ^0.27.3 shared_preferences: ^2.0.8 shimmer: ^2.0.0 smooth_page_indicator: ^1.0.0+2 sticky_grouped_list: ^2.1.0 styled_widget: ^0.4.0+3 textfield_tags: ^2.0.0+1 tuple: ^2.0.0 url_launcher: ^6.0.17 uuid: ^3.0.5 webview_flutter: ^3.0.0

dev_dependencies: auto_route_generator: ^4.0.0 build_runner: ^2.0.0 flutter_test: sdk: flutter freezed: ^2.0.3+1 injectable_generator: ^1.5.3 json_serializable: ^6.1.4 lint: ^1.1.1 objectbox_generator: ^1.5.0 retrofit_generator: null

flutter_icons: ios: true android: "launcher_icon" image_path: "assets/logoApp.png"

flutter: uses-material-design: true

fonts:



- Did you find any workarounds to prevent the issue?
Using `flutter pub run build_runner watch --delete-conflicting-outputs` and changing just one of the entity's `@Id(assignable: )` from `true` to `false` does the trick sometimes. 
awaik commented 1 year ago

I faced the same issue, there is some kind of conflict with auto_route generator https://github.com/objectbox/objectbox-dart/issues/414

greenrobot-team commented 1 year ago

@awaik Thanks for answering! My comment also applies here: if you ever find out if this is because something ObjectBox can improve, let us know!

github-actions[bot] commented 1 year ago

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.

EvgeniShmakov commented 1 year ago

In my case it happens because objectbox runs BEFORE freezed. You can verify it here: .dart_tool/build/entrypoint/build.dart After manual order changing it works if you run this dart file manually. But build_runner re-creates the old order. So far I did not find how to order builders.

vlado-rudenok commented 1 year ago

In my case it happens because objectbox runs BEFORE freezed. You can verify it here: .dart_tool/build/entrypoint/build.dart After manual order changing it works if you run this dart file manually. But build_runner re-creates the old order. So far I did not find how to order builders.

Resolved this issue by extending runs_before parameter for freezed package (freezed/packages/freezed/build.yaml): runs_before: ["json_serializable|json_serializable", "objectbox_generator|resolver", "objectbox_generator|generator"]

jakoss commented 1 year ago

@vlado-rudenok Are you planning on doing PR to freezed package with that?

greenrobot-team commented 1 year ago

The freezed author commented that

If you want to make a code generator that runs after Freezed, you can do that inside your own build.yaml instead of Frrezed's You might want to edit Object Box's build.yaml to tell it to run after Freezed

So to support ordering with any other code generator, is it possible to define order of generators in a custom build.yaml file (e.g. we could provide an example for freezed)? Or do we need to ship this change in our library? https://github.com/dart-lang/build/blob/master/build_config/README.md#adjusting-builder-ordering

greenrobot-team commented 1 year ago

Just stumbled onto this, so leaving it here: https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-adjust-builder-ordering says it's possible to define ordering in your build.yaml file:

global_options:
  freezed:freezed:
    runs_before:
      - objectbox_generator:resolver

With this it should be possible to make freezed run before the ObjectBox generator. Will have a look.

endasan commented 1 year ago

Is there any clarity on the plans to support these global_options?

greenrobot-team commented 1 year ago

@endasan If it works, this is not something the ObjectBox package can fix. We could only provide documentation on how to add this to a build.yaml file in your package.