0

(Samples in Kotlin)

I have an entity with manually assigned IDs:

@Entity
@Table(name = "Item")
class Item {
  @Id
  @Column(name = "ItemId", nullable = false, updatable = false)
  var id: Int? = null

  @Column(name = "Name", nullable = false)
  var name: String? = null
}

and the Spring Data REST repository for it:

interface ItemRepository : PagingAndSortingRepository<Item, Int>

If I do a POST to /items using an existing ID, the existing object is overwritten. I would expect it to throw back an error. Is there a way to configure that behavior without rolling my own save method for each resource type?

Thanks.

2 Answers 2

1

I ended up using a Spring Validator for this with the help of this article.

I created the validator like this:

class BeforeCreateItemValidator(private val itemRepository: ItemRepository) : Validator {
    override fun supports(clazz: Class<*>) = Item::class.java == clazz

    override fun validate(target: Any, errors: Errors) {
        if (target is Item) {
            itemRepository
                .findById(target.id!!)
                .ifPresent {
                    errors.rejectValue("id",
                                       "item.exists",
                                       arrayOf(target.id.toString()),
                                       "no default message")
                }
        }
    }
}

And then set it up with this configuration:

@Configuration
class RestRepositoryConfiguration(
        private val beforeCreateItemValidator: BeforeCreateItemValidator
    ) : RepositoryRestConfigurer {

    override fun configureValidatingRepositoryEventListener(
        validatingListener: ValidatingRepositoryEventListener) {
        validatingListener.addValidator("beforeCreate", beforeCreateItemValidator)
    }
}

Doing this causes the server to return a 400 Bad Request (I'd prefer the ability to change to a 409 Conflict, but a 400 will do) along with a JSON body with an errors property containing my custom message. This is fine for my purposes of checking one entity, but if my whole application had manually assigned IDs it might get a little messy to have to do it this way. I'd like to see a Spring Data REST configuration option to just disable overwrites.

Sign up to request clarification or add additional context in comments.

Comments

0

You can add a version attribute to the entity annotated with @Version this will enable optimistic locking. If you provide always the version 0 with new entities you'll should get an exception when that entity does already exist (with a different version).

Of course you then need to provide that version for updates as well.

1 Comment

Found my own (different) solution before I got a chance to try this. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.