2

I've tried many different ways to pass an array of JSON to a Spring Data Rest Repository, not sure how to do it. I have a custom respository interface that is extending Repository:

@NoRepositoryBean
interface BaseRepository<T, ID extends Serializable> extends Repository<T, Long> {

    T save(T entity)

    List<T> save(Iterable<T> entities)

}

I can save a single entity, but when I try to pass an array of JSON objects I get an error cannot deserialize instance...

Not sure how to pass the object so that I can do a batch insert.

Hatem Jaber
  • 2,341
  • 2
  • 22
  • 38
  • I think you need a standard Spring MVC controller in this scenario: http://stackoverflow.com/questions/40362789/how-to-save-many-objects-in-the-same-request-using-spring-boot-data-rest – Alan Hay Feb 09 '17 at 17:43

2 Answers2

1

Unfortunatly you don't post the code that uses your interface, bug if you are actually passing an array as you describe in the question, you are not calling List<T> save(Iterable<T> entities) but T save(T entity). Arrays are not Iterables so the compiler will interpret your array as T and since an array is not an entity you get the error.

Convert the array to an Iterable to fix this. Arrays.asList(someArray) does the trick.

Community
  • 1
  • 1
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
0

I seemed to work around it by overriding the save method, I'm sure there is a better way, I am open to suggestions.

BaseRepository

@NoRepositoryBean
interface BaseRepository<T, ID extends Serializable> extends Repository<T, Long> {

    @RestResource(path="byIdIn",rel="byIdIn")
    @Query("select r from #{#entityName} r where r.id in :q")
    Page<T> findByIdIn(@Param("q") List<Long> q, Pageable pageable)

    Page<T> findAll(Pageable pageable)

    T findOne(ID id)    

    T save(T entity)

    T delete(ID id)

}

ContactRepository

@RepositoryRestResource(collectionResourceRel="contacts", path="contacts")
interface ContactRepository extends BaseRepository<Contact, Long>, ContactRepositoryCustom {

}

ContactRepositoryCustom

interface ContactRepositoryCustom  {
    public <S extends Contact> S save(S entity)

}

ContactRepositoryImpl

@NoRepositoryBean
class ContactRepositoryImpl implements ContactRepositoryCustom {

    @PersistenceContext
    private EntityManager em

    @Transactional
    @Override
    public <S extends Contact> S save(S entity) {
        Contact contact = entity as Contact
        try {
            em.persist(contact)
            contact.getComment().each {
                Comment comment = new Comment(contact, it)
                em.persist(comment)
            }
        } catch (Exception e) {
            println e
        }
        return contact
    }

}

This is just a sample, it needs some cleaning up, but I have the save() method working as expected. I just don't want to over do it if there is a baked in way in Spring Data / Spring Data Rest to do this kind of thing with annotations without having to roll a solution like this. I searched through the docs and online, but did not find a solution. I may have overlooked something, not sure.

Hatem Jaber
  • 2,341
  • 2
  • 22
  • 38