Skip to content

Android codegen bug: implicit @BelongsTo annotation not being applied to generated child models #102

Open
@raphkim

Description

@raphkim

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmodel-genIssues on datastore model generationp2

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions