5
votes

We are currently implementing an API library in our newest project. We are trying to use Spring HATEOAS with HAL as the apropriate library to generate json hal responsed.

Using Spring boot 1.2.5.RELEASE + the provided Spring HATEOAS version. Currently we are mapping the actual JPA entities to be returned as Resources.

I.e. our entity looks like this:

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
@Table(name = "users")
public class User {

    @Id
    private UUID id;

    @Column(nullable = false, length = 70)
    private String firstName;

    @Column(nullable = false, length = 70)
    private String lastName;
}

Our repository:

public interface UserRepository extends PagingAndSortingRepository<User, UUID>, JpaSpecificationExecutor<User> {
    User findByUsername(String username);
}

Our service:

@Service
@Transactional
public class UserService implements UserDetailsService {

    private UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public Page<User> findAll(Pageable pageable) {
        return this.userRepository.findAll(pageable);
    }
}

The RestController:

@RestController
@RequestMapping(value = "/users", produces =MediaType.APPLICATION_JSON_VALUE) // this is done otherwise objectmapper returns xml for some reason
public UserRestController {

    public UserService userService;
    public EntityLinks entityLinks;

    @Autowired
    public UserRestController(UserService userService, EntityLinks entityLinks) {
        this.userService = userService;
        this.entityLinks = entityLinks;
    }

    @RequestMapping(method = RequestMethod.GET)
    public PagedResource<Resource<User>> getUsers(Pageable pageable, PagedResourcesAssembler<User> pagedResourcesAssembler) {
        Page<User> userPage = this.userService.findAll(pageable);

        PagedResources<Resource<User>> userPagedResources =
            pagedResourcesAssembler.toResource(
                    usersPage,
                    linkTo(methodOn(UserRestController.class).showUsers(pageable, pagedResourcesAssembler)).withSelfRel());

        return userPagedResources;

    }
}

Lets say i set the default page size to 1 the pages are getting generated apropriately. Setting the links to prev/next page. The 'embeddable' attribute is being generated but then we get "userList": [{user}] on page one and page two gets us "user$$_jvst163_9List": [{user}].

Is there a way to actually name the page list property (i've been trying to find something on the net but no avail).

For example:

{
  "_links": {
    "self": {
      "href": "http://localhost:8080/users{?page,size,sort}",
      "templated": true
    },
    "next": {
      "href": "http://localhost:8080/users?page=1&size=1&sort=firstname,lastname,asc"
    }
  },
  "_embedded": {
    "userList": [{
      "id": "2027bea9-cfdc-4724-b29c-39b3f64cbfd5",
      "firstname": "admin",
      "lastname": "asdf",
    }]
  },
  "page": {
    "size": 1,
    "totalElements": 2,
    "totalPages": 2,
    "number": 0
  }
}
{
  "_links": {
    "self": {
      "href": "http://localhost:8080/users{?page,size,sort}",
      "templated": true
    },
    "prev": {
      "href": "http://localhost:8080/users?page=0&size=1&sort=firstname,lastname,asc"
    }
  },
  "_embedded": {
    "user_$$_jvst163_9List": [{
      "id": "52c0c09e-c386-4aec-9723-f8beaf99adc5",
      "username": "admin",,
      "firstname": "firstname",
      "lastname": "lastname"
    }]
  },
  "page": {
    "size": 1,
    "totalElements": 2,
    "totalPages": 2,
    "number": 1
  }
}
1
Solved the issue by using the @Relation from the Spring HATEOAS package. I.e. @Relation(collectionRelation = "users")Konstantin
feel free to answer your own question, and provide details to make it useful for others!Raman

1 Answers

9
votes

As I understand the authors own comment to the question, the solution found was to add the @Relation(collectionRelation = "users") to the User class.

...
@Table(name = "users")
@Relation(collectionRelation = "users")
public class User {
...