////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
////

Write operations in Data Services are automatically wrapped in a transaction. You can modify the transactional attributes by simply adding the `@Transactional` transformation to any method.

The following sections discuss the details of the different write operations.

==== Create

To create a new entity the method should return the new entity and feature either the parameters to be used to create the entity or the entity itself.

For example:

[source,groovy]
----
@Service(Book)
interface BookService {
    Book saveBook(String title)

    Book saveBook(Book newBook)
}
----

If any of the parameters don't match up to a property on the domain class then a compilation error will occur.

If a validation error occurs then a `ValidationException` will be thrown from the service.

==== Update

Update operations are similar to Create operations, the main difference being that the first argument should be the `id` of the object to update.

For example:

[source,groovy]
----
@Service(Book)
interface BookService {
    Book updateBook(Serializable id, String title)
}
----

If any of the parameters don't match up to a property on the domain class then a compilation error will occur.

If a validation error occurs then a `ValidationException` will be thrown from the service.

You can also implement update operations using JPA-QL:

[source,groovy]
----
@Query("update ${Book book} set ${book.title} = $newTitle where $book.title = $oldTitle")
Number updateTitle(String newTitle, String oldTitle)
----

==== Delete

Delete operations can either return `void` or return the instance that was deleted. In the latter case an extra query is required to fetch the entity prior to issue a delete.

[source,groovy]
----
@Service(Book)
interface BookService {
    Number deleteAll(String title)

    void delete(Serializable id)
}
----

You can also implement delete operations using JPA-QL:

[source,groovy]
----
@Query("delete ${Book book} where $book.title = $title")
void delete(String title)
----

Or via where queries:

[source,groovy]
----
@Where({ title == title && releaseDate > date })
void delete(String title, Date date)
----
