aws-amplify / aws-amplify/amplify-codegen

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

Open
#102 10 comments 0 reactions 0 assignees View on GitHub
bug model-gen p2
Dominant language
TypeScript
Stars
59
Forks
64
PR merge metrics
No merged PRs in 30d

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 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 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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.