Added showcase for JDK 8's Optional support on repository methods.

Abbreviated JPA sample module folder names. Renamed the Java 8 auditing sample module to Java 8 module as it not only contains samples for auditing anymore.
This commit is contained in:
Oliver Gierke
2014-04-22 14:48:00 +02:00
parent dadaf374c3
commit 0ddb2ba0d6
74 changed files with 95 additions and 19 deletions

View File

@@ -20,6 +20,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0.1</version>
</dependency>
</dependencies>

View File

@@ -21,6 +21,8 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import com.google.common.base.Optional;
/**
* Simple repository interface for {@link User} instances. The interface is used to declare so called query methods,
* methods to retrieve single entities or collections of them.
@@ -39,6 +41,8 @@ public interface SimpleUserRepository extends CrudRepository<User, Long> {
*/
User findByTheUsersName(String username);
Optional<User> findByUsername(String username);
/**
* Find all users with the given lastname. This method will be translated into a query by constructing it directly
* from the method name as there is no other query declared.

View File

@@ -15,6 +15,7 @@
*/
package example.springdata.jpa.simple;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.util.List;
@@ -27,10 +28,6 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import example.springdata.jpa.simple.SimpleConfiguration;
import example.springdata.jpa.simple.SimpleUserRepository;
import example.springdata.jpa.simple.User;
/**
* Intergration test showing the basic usage of {@link SimpleUserRepository}.
*
@@ -47,6 +44,7 @@ public class SimpleUserRepositoryTests {
@Before
public void setUp() {
user = new User();
user.setUsername("foobar");
user.setFirstname("firstname");
@@ -58,7 +56,7 @@ public class SimpleUserRepositoryTests {
user = repository.save(user);
assertEquals(user, repository.findOne(user.getId()));
assertThat(repository.findOne(user.getId()), is(user));
}
@Test
@@ -68,8 +66,8 @@ public class SimpleUserRepositoryTests {
List<User> users = repository.findByLastname("lastname");
assertNotNull(users);
assertTrue(users.contains(user));
assertThat(users, is(notNullValue()));
assertThat(users.contains(user), is(true));
}
@Test
@@ -79,6 +77,16 @@ public class SimpleUserRepositoryTests {
List<User> users = repository.findByFirstnameOrLastname("lastname");
assertTrue(users.contains(user));
assertThat(users.contains(user), is(true));
}
@Test
public void useGuavaOptionalInsteadOfNulls() {
assertThat(repository.findByUsername("foobar").isPresent(), is(false));
repository.save(user);
assertThat(repository.findByUsername("foobar").isPresent(), is(true));
}
}

23
jpa/java8/README.md Normal file
View File

@@ -0,0 +1,23 @@
# Spring Data - Java 8 examples
This project contains samples of Java 8 specific features of Spring Data (JPA).
## Support for JDK 8's `Optional` for repository methods
```java
interface CustomerRepository extends Repository<Customer, Long> {
// CRUD method using Optional
Optional<Customer> findOne(Long id);
// Query method using Optional
Optional<Customer> findByLastname(String lastname);
}
```
* `CustomerRepository.findOne(Long)` effectively "overrides" the default `CrudRepository.findOne(…)` to return `Optional.empty()` instead of `null` in case no uniqe element satisfying the query can be found.
* `CustomerRepository.findByLastname(…)` does the same for a normal query method.
## Support for JDK 8's date/time types in the auditing sub-system
* `Customer` extends `AbstractEntity` which contains fields of JDK 8's new date/time API and those can be populated the same way legacy types like `Date` and `Calendar` can.

View File

@@ -8,8 +8,8 @@
<version>1.0.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-data-jpa-java8-auditing</artifactId>
<name>Spring Data JPA - Auditing on Java 8</name>
<artifactId>spring-data-jpa-java8</artifactId>
<name>Spring Data JPA - Java 8 specific features</name>
<dependencies>

View File

@@ -21,6 +21,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@Configuration
@EnableAutoConfiguration
@EnableJpaAuditing class AuditingConfiguration {
@EnableJpaAuditing
class AuditingConfiguration {
}
}

View File

@@ -15,11 +15,25 @@
*/
package example.springdata.jpa.java8;
import java.util.Optional;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.Repository;
/**
* Repository to manage {@link Customer} instances.
*
* @author Oliver Gierke
*/
public interface CustomerRepository extends CrudRepository<Customer, Long> {
public interface CustomerRepository extends Repository<Customer, Long> {
/**
* Special customization of {@link CrudRepository#findOne(java.io.Serializable)} to return a JDK 8 {@link Optional}.
*
* @param id
* @return
*/
Optional<Customer> findOne(Long id);
<S extends Customer> S save(S customer);
}

View File

@@ -18,11 +18,14 @@ package example.springdata.jpa.java8;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
* Integration test to show the usage of Java 8 date time APIs with Spring Data JPA auditing.
@@ -31,10 +34,20 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AuditingConfiguration.class)
public class Java8AuditingIntegrationTests {
@Transactional
public class Java8IntegrationTests {
@Autowired CustomerRepository repository;
@Test
public void providesFindOneWithOptional() {
Customer carter = repository.save(new Customer("Carter", "Beauford"));
assertThat(repository.findOne(carter.id).isPresent(), is(true));
assertThat(repository.findOne(carter.id + 1), is(Optional.<Customer> empty()));
}
@Test
public void auditingSetsJdk8DateTimeTypes() {

View File

@@ -17,14 +17,14 @@
<inceptionYear>2011</inceptionYear>
<modules>
<module>spring-data-jpa-example</module>
<module>spring-data-jpa-showcase</module>
<module>spring-data-jpa-interceptors</module>
<module>spring-data-jpa-java8-auditing</module>
<module>example</module>
<module>showcase</module>
<module>interceptors</module>
<module>java8</module>
</modules>
<properties>
<spring-data-jpa.version>1.5.1.RELEASE</spring-data-jpa.version>
<spring-data-jpa.version>1.6.0.BUILD-SNAPSHOT</spring-data-jpa.version>
<hibernate-entitymanager.version>4.3.4.Final</hibernate-entitymanager.version>
</properties>
@@ -47,4 +47,11 @@
</dependencies>
<repositories>
<repository>
<id>spring-libs-snapshot</id>
<url>http:/repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
</project>