Description
Issue
When the customer creates a GraphQL model schema with either hasOne or hasMany relationship, they are only required to explicitly specify @connection
directive on the parent model (they do not need to explicitly mention belongsTo relationship on the child model). However, every relationship must be bi-directional and codegen should still generate child model with belongsTo relationship.
Currently, android codegen does not behave this way and does not generate child model correctly.
Schema for reference:
type Post @model {
id: ID!
title: String!
comments: [Comment] @connection(keyName: "byPost", fields: ["id"])
}
type Comment @model
@key(name: "byPost", fields: ["postID", "content"]) {
id: ID!
postID: ID!
content: String!
}
This explicitly specifies a connection that Post
has many Comment
, but does not specify a connection directive on the Comment
side. This results in java codegen forming a @HasMany
relationship on the Post
side but generates a Comment
model without @BelongsTo
connection to other models. Android DataStore depends on the explicit presence of this annotation when generating foreign key relationships.
Currently behavior:
public final class Post implements Model {
private final @ModelField(targetType="ID", isRequired = true) String id;
private final @ModelField(targetType="String", isRequired = true) String title;
private final @ModelField(targetType="Comment") @HasMany(associatedWith = "postID", type = Comment.class) List<Comment> comments = null;
...
}
public final class Comment implements Model {
private final @ModelField(targetType="ID", isRequired = true) String id;
private final @ModelField(targetType="ID", isRequired = true) String postID;
private final @ModelField(targetType="String", isRequired = true) String content;
...
}
Expected behavior:
public final class Post implements Model {
private final @ModelField(targetType="ID", isRequired = true) String id;
private final @ModelField(targetType="String", isRequired = true) String title;
private final @ModelField(targetType="Comment") @HasMany(associatedWith = "post", type = Comment.class) List<Comment> comments = null;
...
}
public final class Comment implements Model {
private final @ModelField(targetType="ID", isRequired = true) String id;
private final @ModelField(targetType="Post", isRequired = true) @BelongsTo(targetName = "postID", type = Post.class) Post post;
private final @ModelField(targetType="String", isRequired = true) String content;
...
}
Note: This is a requirement for both one-to-one and one-to-many relationships