Group dynamic attributes by category in REST

Hi team,

Jmix version: 2.1

Suppose I have 2 categories of dynamic attributes named cate1 and cat2, is it possible to extend some bean to make it showing cat1:{prop1:'xxx'},cat2:{prop2:'xxx'} in the output of REST when loading entities?

Hello!

Solution using DynAttr API

We can find all categories just from database, iterate over it’s attributes and using DynAttr API fetch it all:

@RestController
@RequestMapping("rest/users/")
public class UserController {
    @Autowired
    public DataManager dataManager;
    @Autowired
    public ExtendedEntities extendedEntities;
    @Autowired
    public Metadata metadata;


    @GetMapping("list")
    public List<Map<User, Map<String, Map<String, Object>>>> listUsers() {

        List<Category> categoriesForUser = dataManager.load(Category.class)
                .query("select e from dynat_Category e where e.entityType = :entityType")
                .parameter("entityType", metadata.getClass(User.class).getName())
                .list();

        return dataManager.load(User.class)
                .all()
                .hint(DynAttrQueryHints.LOAD_DYN_ATTR, true)
                .list()
                .stream()
                .map(user -> {
                    Map<User, Map<String, Map<String, Object>>> dynAttrMapping = new HashMap<>();
                    var userAttrs = categoriesForUser.stream()
                            .collect(Collectors.toMap(Category::getName,
                                    c -> c.getCategoryAttrs()
                                            .stream()
                                            .collect(Collectors.toMap(CategoryAttribute::getCode,
                                                    a -> {
                                                        var value = EntityValues.getValue(user, "+" + a.getCode());
                                                        return Objects.requireNonNullElse(value, "null");
                                                    }
                                            ))));

                    dynAttrMapping.put(user, userAttrs);
                    return dynAttrMapping;
                })
                .toList();
    }
}

Result:

image

Regards, Dmitry

1 Like