2

I tried to implement entity classes using polymorphism.

This is my BaseEntity

@Getter
@Setter
@Accessors(chain = true)
@MappedSuperclass
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Size(max = 55, message = "name length more then 55")
  private String name;

  @Size(max = 255, message = "remark length more than 255")
  private String remark;

}

And my entity

@Data
@NoArgsConstructor
@Table(name = "sys_user")
@Entity(name = "sys_user")
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class SysUser extends BaseEntity implements Serializable {

  @NonNull
  private String username;

  @NonNull
  private String password;

}

In my controller

@Controller
@GraphQLApi
@RequiredArgsConstructor
public class SysUserController implements BaseController {

  private final SysUserRepository sysUserRepository;

  @GraphQLQuery
  public List<SysUser> sysUsers() {
    return sysUserRepository.findAll();
  }

}

My GraphQL Config

@Configuration
@RequiredArgsConstructor
public class GraphQLConfig {

  private final @NotNull List<BaseController> controllerLists;

  @Bean
  public GraphQLSchema graphqlSchema() {
    GraphQLSchemaGenerator generator = new GraphQLSchemaGenerator();
    generator.withOperationsFromSingletons(controllerLists.toArray());
    return generator.generate();
  }

}

Now, I try to get

{
  sysUsers {
    username
  }
}

The result is right

{
  "data": {
    "sysUsers": [
      {
        "username": "Hello"
      }
    ]
  }
}

But I try to get the parent class field:

{
  sysUsers {
    name
  }
}

I will get a error

{
  "errors": [
    {
      "message": "Validation error of type FieldUndefined: Field 'name' in type 'SysUser' is undefined @ 'sysUsers/name'",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ]
    }
  ]
}

I use io.leangen.graphql:graphql-spqr-spring-boot-starter:0.0.4

How to resolve this question?

Thanks!

kaqqao
  • 12,984
  • 10
  • 64
  • 118
EchoCow
  • 163
  • 8

2 Answers2

0

Inherited fields will only be exposed if they're within the configured packages. This way, you don't accidentally expose framework fields, JDK fields (like hashCode) etc. If no base packages are configured, SPQR will stay within the package the directly exposed class is.

To configure the base packages, add something like:

graphql.spqr.base-packages=your.root.package,your.other.root.package

to your application.properties file.

Note: These rules will get relaxed in the next release of SPQR, so that all non-JDK fields are exposed by default, as the current behavior seems to confuse too many people.

kaqqao
  • 12,984
  • 10
  • 64
  • 118
0

I'd recommend you to add auto-generation of classes based on the types defined in your graphql schema. It will provide you more clarity on what is exposed to the user and avoid such errors in future. Here are the plugins:

Bogdan Kobylynskyi
  • 1,150
  • 1
  • 12
  • 34