hive
hive copied to clipboard
After updating HiveObject its key will become null
I think it's a bug, why is the key changing to null if it's must be constant? But I want to say that the key is not changing internally in the hive box, it's still the same, but HiveObject for some reason holds null after the update, in order to fix this I need to hot restart my app.
Reproducible code example with dependencies is provided below:
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
part 'main.g.dart';
// dependencies:
// hive: ^2.0.5
// hive_flutter: ^1.1.0
// path_provider: ^2.0.8
// build_runner: ^2.1.7
// hive_generator: ^1.1.2
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final directory = await getApplicationDocumentsDirectory();
Hive.init(directory.path);
Hive.registerAdapter(MyModelAdapter());
await Hive.openBox<MyModel>('my_model');
Hive.box<MyModel>('my_model').add(MyModel('Test'));
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late MyModel test;
@override
void initState() {
test = Hive.box<MyModel>('my_model').values.first;
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(),
// 2. Check how key will become null
// Accepted behaviour: key must not be null
Text(
'Model ${test.name} Key: ${test.key}',
),
// 1. Tap this button
TextButton(
onPressed: () {
Hive.box<MyModel>('my_model').put(
test.key,
MyModel('Test ${DateTime.now().second}'),
);
setState(() {});
},
child: const Text('update'),
),
],
),
),
);
}
}
@HiveType(typeId: 0)
class MyModel extends HiveObject {
MyModel(this.name);
@HiveField(0)
final String name;
}
Similar is happening with my code. When I tried to update an item with put method , the key is null. Do you get any solution?
I have the same problem, any news about this?
It is probably null because you did not add @HiveField to the second adapter.
I can't comment because I can't see the model, but you should use a structure similar to this.
I think you probably forgot to use HiveField in class Geys extends HiveObject.
And You should add all adapters in main like this;
Hive.registerAdapter(GGGAdapter());
Hive.registerAdapter(GeysAdapter());
part 'denememodel.g.dart';
@HiveType(typeId: 0)
class GGG extends HiveObject {
@HiveField(0)
List<Geys>? geys;
@HiveField(1)
GGG({this.geys});
GGG.fromJson(Map<String, dynamic> json) {
if (json['geys'] != null) {
geys = <Geys>[];
json['geys'].forEach((v) {
geys!.add(new Geys.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.geys != null) {
data['geys'] = this.geys!.map((v) => v.toJson()).toList();
}
return data;
}
}
@HiveType(typeId: 1)
class Geys extends HiveObject {
@HiveField(0)
String? id;
@HiveField(1)
String? author;
Geys({this.id, this.author});
Geys.fromJson(Map<String, dynamic> json) {
id = json['id'];
author = json['author'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['author'] = this.author;
return data;
}
} `
Similar is happening with my code, any solution?
I suppose this is simply because when a new object is being added into the hive database, the new object gets the key.
onPressed: () {
int index = test.key; // we store this because we will be assigning test to a new object, which doesn't have the key
test = MyModel('Test ${DateTime.now().second}'); // assign test to a new object
Hive.box<MyModel>('my_model').put(index, test); // now the new object will have the key
setState(() {});
}
In the previous example by @eli1stark , the temporary model created within the function is getting the key
in short, the key is binded with the actual object in the database, I believe