isar / hive

Lightweight and blazing fast key-value database written in pure Dart.
Apache License 2.0
4.02k stars 399 forks source link

[hive_generator] not generating type adapter for freezed class #795

Open casvanluijtelaar opened 2 years ago

casvanluijtelaar commented 2 years ago

I'm attempting to generate a type adapter for my freezed class basing myself of the examples in https://github.com/hivedb/hive/issues/225. It will generate the DeviceStatus adapter just fine. but not the WledDevice no code gets generated and no errors are thrown

part 'wled_device.freezed.dart';
part 'wled_device.g.dart';

@HiveType(typeId: 2)
enum DeviceStatus {
  @HiveField(0)
  functional,
  @HiveField(1)
  unreachable,
  @HiveField(2)
  error,
}

@freezed 
class WledDevice with _$WledDevice {

  @ColorConverter()
  @HiveType(typeId: 0, adapterName: 'WledDeviceAdapter')
  const factory WledDevice({
    // device IP (can also be hostname if applicable)
    @HiveField(0) required String address,
    // device display name ("Server Description")
    @HiveField(1) required String name,
    // Current connection status
    @HiveField(2) @Default(DeviceStatus.functional) DeviceStatus status,
    // If the light name is custom, the name returned
    // by the API response will be ignored
    @HiveField(3) @Default(false) bool nameIsCustom,
    // if the wled device is saved to the local device
    @HiveField(4) @Default(false) bool isSaved,
    // Disabled devices don't get polled or show up in the list
    @HiveField(5) @Default(true) bool isEnabled,
    // There are two vars for brightness to discern
    // API responses from slider updates
    @HiveField(6) @Default(0.9) double brightness,
    // the currently active device color
    @HiveField(7) @Default(ColorConverter.defaultColor) @JsonKey() Color color,
  }) = _WledDevice;

  factory WledDevice.fromJson(Map<String, dynamic> json) =>
      _$WledDeviceFromJson(json);
}
pubspec.yaml & build_runner output ``` yaml name: wled description: A cross-platform application for interacting with WLED devices version: 1.0.0 environment: sdk: ">=2.12.0 <3.0.0" dependencies: auto_route: ^2.3.0 bloc: ^7.2.0-dev.3 bloc_concurrency: ^0.1.0-dev.2 flutter: sdk: flutter flutter_bloc: ^7.2.0 flutter_feather_icons: ^2.0.0+1 flutter_localizations: sdk: flutter freezed_annotation: ^0.14.3 get_it: ^7.2.0 hive: ^2.0.4 hive_flutter: ^1.1.0 http: ^0.13.3 injectable: ^1.5.0 json_annotation: ^4.1.0 multicast_dns: ^0.3.1 rive: ^0.7.28 rxdart: ^0.27.2 sleek_circular_slider: ^2.0.1 webview_flutter: ^2.0.14 xml: ^5.1.0 dev_dependencies: auto_route_generator: ^2.3.0 build_runner: ^2.1.2 flutter_app_name: ^0.1.0 flutter_launcher_icons: "^0.9.2" flutter_native_splash: ^1.2.3 freezed: ^0.14.5 hive_generator: ^1.1.1 injectable_generator: ^1.5.1 json_serializable: ^5.0.1 very_good_analysis: ^2.3.0 dependency_overrides: meta: ^1.7.0 flutter: uses-material-design: true assets: - assets/rive/ fonts: - family: Nunito fonts: - asset: fonts/Nunito-Bold.ttf weight: 700 - asset: fonts/Nunito-Regular.ttf weight: 400 # internationalization settings flutter_intl: enabled: true class_name: Localization arb_dir: lib/core/l10n output_dir: lib/core/l10n/generated # set flutter splash screen flutter_native_splash: color: "#1D1D1D" image: assets/images/splash.png fullscreen: true android12: false # set flutter app icon flutter_icons: ios: true android: true image_path_ios: "assets/images/fallback.png" image_path_android: "assets/images/fallback.png" adaptive_icon_background: "assets/images/background.png" adaptive_icon_foreground: "assets/images/foreground.png" # set flutter app name flutter_app_name: name: "WLED" ``` ``` powershell flutter pub run build_runner build --delete-confl [INFO] Generating build script... [INFO] Generating build script completed, took 1.0s [INFO] Initializing inputs [INFO] Reading cached asset graph... [INFO] Reading cached asset graph completed, took 1.3s [INFO] Checking for updates since last build... [INFO] Checking for updates since last build completed, took 7.8s [INFO] Running build... [INFO] 1.2s elapsed, 0/10 actions completed. [INFO] 2.6s elapsed, 1/10 actions completed. [INFO] 3.8s elapsed, 1/10 actions completed. [INFO] 4.8s elapsed, 1/10 actions completed. [INFO] 5.8s elapsed, 1/10 actions completed. [INFO] 6.9s elapsed, 1/10 actions completed. [INFO] 23.2s elapsed, 1/10 actions completed. [WARNING] No actions completed for 21.4s, waiting on: - hive_generator:hive_generator on lib/core/app/app_router.dart - hive_generator:hive_generator on lib/features/device_control/bloc/ - hive_generator:hive_generator on lib/features/device_add/bloc/devi - hive_generator:hive_generator on lib/features/device_add/data/repo - hive_generator:hive_generator on lib/core/data/models/wled_device. .. and 4 more [INFO] 24.4s elapsed, 12/15 actions completed. [INFO] 25.4s elapsed, 20/20 actions completed. [INFO] 26.5s elapsed, 23/31 actions completed. [WARNING] json_serializable:json_serializable on lib/core/data/models/ The constructor parameter for `status` has a default value `DeviceStat[WARNING] json_serializable:json_serializable on lib/core/data/models/ The constructor parameter for `nameIsCustom` has a default value `fals [WARNING] json_serializable:json_serializable on lib/core/data/models/ The constructor parameter for `isSaved` has a default value `false`, b [WARNING] json_serializable:json_serializable on lib/core/data/models/ The constructor parameter for `isEnabled` has a default value `true`, [WARNING] json_serializable:json_serializable on lib/core/data/models/ The constructor parameter for `brightness` has a default value `0.9`, [INFO] 28.1s elapsed, 31/31 actions completed. [INFO] 29.2s elapsed, 34/42 actions completed. [INFO] 30.2s elapsed, 36/43 actions completed. [WARNING] auto_route_generator:autoRouteGenerator on lib/core/app/app_ WARNING => Because [DeviceControlView] has required parameters (device @PathParam() and @QueryParam() annotations will be ignored. [INFO] 31.6s elapsed, 43/55 actions completed. [INFO] 32.8s elapsed, 48/63 actions completed. [INFO] 34.0s elapsed, 61/70 actions completed. [INFO] 35.3s elapsed, 73/82 actions completed. [WARNING] injectable_generator:injectable_config_builder on lib/core/a Missing dependencies in wled/core/app/app_injector.dart [DeviceAddBloc] depends on unregistered type [AppRouter] from package: Did you forget to annotate the above class(s) or their implementation with @injectable? or add the right environment keys? ------------------------------------------------------------------------ [INFO] Running build completed, took 35.5s [INFO] Caching finalized dependency graph... [INFO] 36.5s elapsed, 82/82 actions completed. [INFO] Caching finalized dependency graph completed, took 1.2s [INFO] Succeeded after 36.7s with 16 outputs (82 actions) ```
bit-garden commented 2 years ago

I don't use the generator personally, but as I understand, the @HiveType goes above the class definition and the @HiveField goes above the variables, not the arguments of a function.

It looks like for your freezed classes, you may have to roll your adapters manually.

casvanluijtelaar commented 2 years ago

I don't use the generator personally, but as I understand, the @HiveType goes above the class definition and the @HiveField goes above the variables, not the arguments of a function.

It looks like for your freezed classes, you may have to roll your adapters manually.

Thanks for the reply, occording to https://github.com/hivedb/hive/issues/225 the HiveType should be positioned above the factory and not the class (since freezed will generate the propper class and copy the annotation) and the above or before positioning of dart annotations shouldn't matter.

Generated class ``` dart @JsonSerializable() @ColorConverter() @HiveType(typeId: 0, adapterName: 'WledDeviceAdapter') class _$_WledDevice implements _WledDevice { const _$_WledDevice({ @HiveField(0) required this.address, @HiveField(1) required this.name, @HiveField(2) this.status = DeviceStatus.functional, @HiveField(3) this.nameIsCustom = false, @HiveField(4) this.isSaved = false, @HiveField(5) this.isEnabled = true, @HiveField(6) this.brightness = 0.9, @HiveField(7) @JsonKey() this.color = ColorConverter.defaultColor }); @override // device IP (can also be hostname if applicable) @HiveField(0) final String address; @override // device display name ("Server Description") @HiveField(1) final String name; @JsonKey(defaultValue: DeviceStatus.functional) @override // Current connection status @HiveField(2) final DeviceStatus status; @JsonKey(defaultValue: false) @override // If the light name is custom, the name returned @HiveField(3) final bool nameIsCustom; @JsonKey(defaultValue: false) @override // if the wled device is saved to the local device @HiveField(4) final bool isSaved; @JsonKey(defaultValue: true) @override // Disabled devices don't get polled or show up in the list @HiveField(5) final bool isEnabled; @JsonKey(defaultValue: 0.9) @override // There are two vars for brightness to discern @HiveField(6) final double brightness; @override // the currently active device color @HiveField(7) @JsonKey() final Color color; ```
casvanluijtelaar commented 2 years ago

@themisir something related to this build_runner output perhaps?

[WARNING] No actions completed for 17.6s, waiting on:
  - hive_generator:hive_generator on lib/core/app/app_router.dart
  - hive_generator:hive_generator on lib/features/device_add/bloc/device_add_bloc.dart
  - hive_generator:hive_generator on lib/features/device_control/bloc/device_control_bloc.dart
  - hive_generator:hive_generator on lib/features/device_list/bloc/device_list_bloc.dart
  - hive_generator:hive_generator on lib/features/device_add/repository/device_add_repository.dart
  .. and 5 more
TarekkMA commented 2 years ago

I have this same issue, it happened when I upgraded to the latest freezed version ^0.14.5 but when I reverted back to 0.14.1+3 hive_generator worked again.

casvanluijtelaar commented 2 years ago

hmm odd, @rrousselGit I can't see anything in the changelog that would directly break this?

rrousselGit commented 2 years ago

Freezed doesn't care about converters. It's json_serializable that deals with them.

But maybe changing the Frezed version changes the json_serializable version you're using

TarekkMA commented 2 years ago

I managed to workaround this issue by adding the following to force generation from the freezed file

@freezed
class _Dummy with _$_Dummy {
  const factory _Dummy() = __Dummy;
  factory _Dummy.fromJson(Map<String, dynamic> json) => _$_DummyFromJson(json);
}

Still, we need to figure out what is the issue.

casvanluijtelaar commented 2 years ago

I tried both

I have this same issue, it happened when I upgraded to the latest freezed version ^0.14.5 but when I reverted back to 0.14.1+3 hive_generator worked again.

and

I managed to workaround this issue by adding the following to force generation from the freezed file

@freezed
class _Dummy with _$_Dummy {
  const factory _Dummy() = __Dummy;
  factory _Dummy.fromJson(Map<String, dynamic> json) => _$_DummyFromJson(json);
}

Still, we need to figure out what is the issue.

neither worked for me. I've been experimenting with package versions, overriding freezed and hives dependencies, no luck so far.

@themisir @leisim

TarekkMA commented 2 years ago

@casvanluijtelaar did you have the json_serializable package in dev dependencies?

casvanluijtelaar commented 2 years ago

@casvanluijtelaar did you have the json_serializable package in dev dependencies?

Yes

yura2000 commented 2 years ago

Same issue for me. Tried everything. Downgrade to the older versions helps only. Ok for these versions:

dependencies:
  auto_route: ^2.2.0
  flutter:
    sdk: flutter
  freezed: ^0.14.1+2
  hive_flutter: ^1.0.0

dev_dependencies:
  analyzer: ^1.4.0
  auto_route_generator: ^2.1.0
  build_runner: ^2.0.6
  flutter_test:
    sdk: flutter
  hive_generator: ^1.1.0
  json_serializable: ^4.1.0
  retrofit_generator: ^2.0.1
nank1ro commented 2 years ago

Same issue happening, fixed only downgrading all the dependencies as @yura2000 said in the comment above mine.

roubachof commented 2 years ago

Yes hive generator 1.1.1 is incompatible with json_serializable 6.

casvanluijtelaar commented 2 years ago

Yes hive generator 1.1.1 is incompatible with json_serializable 6.

Do you know why it is incompatible? Then we can create a pull request

roubachof commented 2 years ago

no idea, but now I am stuck cause the last version of flutter is incompatible with auto_route 2.1.0 generator, but I cannot upgrade to newest version of the generator cause it requires json_serializable 6 ....

yura2000 commented 2 years ago

The issue in the auto_route_generator package. Without it everything is ok. Workaround for me: I forked the hive package and changed generate output file type to .hive.dart.

andye2004 commented 2 years ago

EDIT: Please ignore everything below, a new day revelas that what was working yesterday is not working today. I have no idea why this is. I'll leave the existing comment in case it gives an idea to someone else.

Original post below.

OK, not sure how much this will help the conversation as I'm pretty new to Dart/Flutter and I haven't spent any time looking into how code generation works but I ran into this problem and was trying a few things to see if I could get it to work.

After a lot of digging around I've discovered that there are a couple of things impacting adapter generation in my project. Like @yura2000, I'm using auto_route and auto_route_generator and I can confirm that this plays a part in preventing the adapters being generated. Based on this I modified my build.yaml file so that hive_generator generator runs before auto_route_generator, e.g.

targets:
  $default:
    builders:
      hive_generator:
        options:
          runs_before:
            - auto_route_generator

After doing this I expected everything to 'just' work. It didn't.

What I have also discovered is that there needs to be a newline at the end of the source file for the adapter to be correctly generated. E.g.

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

part 'demo.freezed.dart';
part 'demo.g.dart';

@freezed
class Demo with _$Demo {
  @HiveType(typeId: 0, adapterName: 'DemoAdapter')
  factory Demo({@HiveField(0)  required int val,}) = _Demo;

  factory Demo.fromJson(Map<String, dynamic> json) => _$DemoFromJson(json);
}

Having just the above content in the source file meant the adapter was NOT generated. Modifying the source file so there is a newline after the closing brace (}) fixed things and the adapter WAS generated, e.g.

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

part 'demo.freezed.dart';
part 'demo.g.dart';

@freezed
class Demo with _$Demo {
  @HiveType(typeId: 0, adapterName: 'DemoAdapter')
  factory Demo({@HiveField(0)  required int val,}) = _Demo;

  factory Demo.fromJson(Map<String, dynamic> json) => _$DemoFromJson(json);
}

I've put together a small project that demonstrates this, feel free to check it out and run build_runner and look at the generated rresults. With the newline at the end of the demo.dart source file everything works flawlessly. Delete the generated files and remove the newline in demo.dart and run the build runner a second time and the adapter will not be generated.

Hopefully this can help people understand why one thing or another doesnt appear to be working for them.

P.S. One annoying thing is, without having auto_route_generator in the mix, the newline at the end makes no difference whatsoever. I have no idea why this is, intuitively it doesnt make sense but maybe once I've built a bit more experience I can dig into the code generation side of things and understand why.

aaqibismail commented 2 years ago

The issue in the auto_route_generator package. Without it everything is ok. Workaround for me: I forked the hive package and changed generate output file type to .hive.dart.

I also removed auto router and it fixed it for me as well, this is with the latest versions of freezed, json_serializable, and hive

AntonLT commented 2 years ago

Any new workarounds?

AntonLT commented 2 years ago

The issue in the auto_route_generator package. Without it everything is ok. Workaround for me: I forked the hive package and changed generate output file type to .hive.dart.

@yura2000 Hey, could you share how you managed to use the forked hive package? Because the repo has 3 packages inside

yura2000 commented 2 years ago

@AntonLT you can use my fork https://github.com/yura2000/hive

AntonLT commented 2 years ago

@yura2000 Yeah, thank you. But how have you added the packages in dependencies in pubspec.yaml?

pattobrien commented 2 years ago

In the past,when I've run into this issue, I was able to temporarily resolve it by making some sort of modification to the file of the Freezed class that was not properly generating the TypeAdapter. Following the non-confirmed solution @andye2004 posted above, instead of modifying the actual class, I was able to resolve the issue and generate the TypeAdapter by simply adding a commented line underneath the Freezed class. If the error appears again, I plan to simply delete that comment to trigger a rebuild and expect that to work.

In short: triggering a genuine modification of a Freezed file seems to resolve the issue, at least temporarily.

definitelyme commented 2 years ago

Thanks @yura2000 your fork did wonders. Here's how i used it

Add to pubspec.yaml

environment:
  sdk: ">=2.17.0-266.5.beta <3.0.0"

dependencies:
   ...
   # For regular Unions
   freezed_annotation: ^2.0.1
   # Lightweight and blazing fast key-value database written in pure Dart. Strongly encrypted using AES-256.
   hive: ^2.1.0
   hive_flutter:
     git:
       url: https://github.com/yura2000/hive.git
       ref: master
       path: hive_flutter/
   ...

dev_dependencies:
  ...
  freezed: ^2.0.2
  json_serializable: ^6.1.6
  hive_generator:
    git:
      url: https://github.com/yura2000/hive.git
      ref: master
      path: hive_generator/

And in my freezed class, notice the part 'user_dto.hive.dart';

part 'user_dto.freezed.dart';
part 'user_dto.g.dart';
part 'user_dto.hive.dart';

@immutable
@Freezed(makeCollectionsUnmodifiable: false)
class UserDTO with _$UserDTO {
  @HiveType(typeId: 1, adapterName: 'UserDTOAdapter')
  const factory UserDTO({
    @HiveField(1) String? uid,
    @HiveField(2) String? firstName,
  }) = _UserDTO;

  const UserDTO._();

  factory UserDTO.fromJson(Map<String, dynamic> json) => _$UserDTOFromJson(json);
}

And if you want to extend HiveObject "to manage your objects easily..."

part 'user_dto.freezed.dart';
part 'user_dto.g.dart';
part 'user_dto.hive.dart';

@unfreezed
class UserDTO extends HiveObject with _$UserDTO {
  @HiveType(typeId: 1, adapterName: 'UserDTOAdapter')
  factory UserDTO({
    @HiveField(1) String? uid,
    @HiveField(2) String? firstName,
  }) = _UserDTO;

  UserDTO._();

  factory UserDTO.fromJson(Map<String, dynamic> json) => _$UserDTOFromJson(json);
}

PS: You must be on the latest version of freezed_annotation to use the @unfreezed annotation

dagmawi-asfaw commented 2 years ago

So i spent some times trying to figure out this issue and here's what I've found.

so I think the issue was hive generator was not passing the fields to inherited classes, because even thought in the lastest version hive supports inhertance I was still getting the same issue.

so my solution was to not use freezed so the type adapter is created directly from the class. and it has worked for me.

here's my pubspec.yaml

environment:
  sdk: ">=2.12.0 <3.0.0"
publish_to: 'none'
dependencies:
  flutter:
    sdk: flutter

   ...
  hive: ^2.2.3
  hive_flutter: ^1.1.0
  auto_route: ^3.2.2
  freezed: ^1.1.0
  freezed_annotation: ^1.1.0
  json_serializable: ^6.1.4
  json_annotation: ^4.4.0
  injectable: ^1.4.1
  ...

dev_dependencies:
  flutter_test:
    sdk: flutter
   ...
   build_runner: ^2.0.1
   injectable_generator: ^1.4.1
   auto_route_generator: ^3.2.1
   hive_generator: ^1.1.3
   ...

and the hive model class looks like this

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

part 'activity_model.g.dart';

@JsonSerializable()
@HiveType(typeId: 3)
class ActivityModel {
  ActivityModel({
   required this.id,
    this.parentCategory,
    required this.name,
    required this.isCategory,
  });

  @HiveField(0)
  @JsonKey(name: 'id')
  final int id;

  @HiveField(1)
  @JsonKey(name: 'parent_category')
  final ActivityModel? parentCategory;

  @HiveField(2)
  @JsonKey(name: 'name')
  final String name;

  @HiveField(3)
  @JsonKey(name: 'is_category')
  final bool isCategory;

  factory ActivityModel.fromJson(Map<String, dynamic> json) =>
      _$ActivityModelFromJson(json);
}
riyaspullurofficial commented 2 years ago

try this command flutter packages pub run build_runner watch --use-polling-watcher --delete-conflicting-outputs

michelinaFolino commented 1 year ago

Hi guys,

i am using hive, freeze and autoroute. Unfortunately, the hive adapter is not generated. I used @yura2000 's solution and it works. Do you know when the official version will be released?

riyaspullurofficial commented 1 year ago

its simple

On Wed, Nov 2, 2022 at 11:56 PM michelinaFolino @.***> wrote:

Hi guys,

i am using hive, freeze and autoroute. Unfortunately, the hive adapter is not generated. I used @yura2000 https://github.com/yura2000 's solution and it works. Do you know when the official version will be released?

— Reply to this email directly, view it on GitHub https://github.com/hivedb/hive/issues/795#issuecomment-1301050173, or unsubscribe https://github.com/notifications/unsubscribe-auth/AS3BVHOPRSZA53G5C3YRWELWGKW6NANCNFSM5EVXQ4MA . You are receiving this because you commented.Message ID: @.***>

Miky1190 commented 1 year ago

Hi guys, news?

Remas-Safi commented 1 year ago

Please guys if you can check this problem, Cause I need both freezed and hive adaptor, where is my problem if I put

  @HiveType(typeId: 1, adapterName: 'UserDTOAdapter')

after class, the hive generator won't work for me, and no adaptor is generated while using it before the class name, it is generated but I did check the .g file and it only returns an empty object without initializing any field from the list of fields

This is one code I used, but I did try without abstract, without HiveObject.... and many other suggested solutions online... but still won't work.

This is considered a big problem for me, cause now I have to sacrifice Freezed with its amazing feature, especially copyWith and I have to go manually coding for this... unless someone can suggest other solutions for this, please. I'll be thankful 😃

@freezed
abstract class Cart extends HiveObject with _$Cart {
  Cart._();

  @HiveType(typeId: 5)
  factory Cart({
    @HiveField(1) required String id,
    @HiveField(2) required User user,
    @HiveField(3, defaultValue: 0.0) @Default(0.0) double discount,
    @HiveField(4, defaultValue: 0.0) @Default(0.0) double tax,
  }) = _Cart;

  factory Cart.fromJson(Map<String, dynamic> json) => _$CartFromJson(json);
}
nank1ro commented 1 year ago

as far as I know, this library is going to be deprecated very soon in favor of isar. Reference: https://twitter.com/simcdev/status/1656830248955314176

poltavskiymc commented 1 year ago

Hello all! I have a solution for this problem. We found it with team.

If you're using Hive and Freezed, for adapter generation, do next.

  1. You need build_runner (You have it, if use Hive)
  2. Make file "build.yaml" in root of project, near pubspec.yaml. (You can read more here https://github.com/dart-lang/build/blob/master/build_config/README.md)
  3. Paste this in "build.yaml" `global_options: freezed:freezed: runs_before:
    • hive_generator:hive_generator`

It is important to observe the indents, like this: Снимок экрана 2023-05-18 в 10 27 52

  1. Run build_runner. "flutter pub run build_runner build --delete-conflicting-outputs"
  2. Check ".g.dart" file of your model.

This is model for example:

Снимок экрана 2023-05-18 в 10 32 25

Flutter 3.7.5/Dart 2.19.2

hive_generator ^2.0.0 build_runner: ^2.1.10 freezed: ^2.3.2 freezed_annotation: ^2.2.0

alejandro-rios commented 1 year ago

@poltavskiymc the targets part from your build.yaml file is required for the solution?, if it is, can you explain what it does?

edgarfroes commented 10 months ago

@alejandro-rios you don't need to have anything else on the build.yaml file. Also, I think that @poltavskiymc yaml syntax is wrong. I created a build.yaml file with only the following content and it worked. The IDE kept complaining about missing concrete implementations of some Hive methods, but sometimes it wouldn't complain, I can't tell why.

global_options:
  hive_generator:
    runs_before:
      - freezed

Edit: I've changed the main constructor to private and it worked.