Initial commit.
Moved Spring Data JPA examples from spring-data-jpa-examples repo to this one. Added samples for MongoDB.
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.project
|
||||
.classpath
|
||||
.springBeans
|
||||
.settings/
|
||||
target/
|
||||
18
README.md
18
README.md
@@ -1,4 +1,16 @@
|
||||
spring-data-examples
|
||||
====================
|
||||
# Spring Data Examples
|
||||
|
||||
Spring Data Example Projects
|
||||
This repository contains example projects for the different Spring Data modules to showcase the API and how to use the features provided by the modules.
|
||||
|
||||
We have separate folders for the samples of individual modules:
|
||||
|
||||
## Spring Data JPA
|
||||
|
||||
* `spring-data-jpa-example` - Probably the project you want to have a look at first. Contains a variety of sample packages, showcasing the different levels at which you can use Spring Data JPA. Have a look at the `simple` package for the most basic setup.
|
||||
* `java8-auditing` - Example of how to use Spring Data JPA auditing with Java 8 date time types.
|
||||
* `spring-data-jpa-showcase` - Refactoring show case of how to improve a plain-JPA-based persistence layer by using Spring Data JPA (read: removing close to all of the implementation code). Follow the `demo.txt` file for detailed instructions.
|
||||
* `spring-data-jpa-interceptors` - Example of how to enrich the repositories with AOP.
|
||||
|
||||
## Spring Data MongoDB
|
||||
|
||||
* `spring-data-mongodb-example` - Example project for general repository functionality as well as aggregation framework support.
|
||||
|
||||
50
jpa/pom.xml
Normal file
50
jpa/pom.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-jpa-examples</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data JPA - Examples</name>
|
||||
<description>Sample projects for Spring Data JPA</description>
|
||||
<url>http://www.springframework.org/spring-data</url>
|
||||
<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>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<spring-data-jpa.version>1.5.0.RC1</spring-data-jpa.version>
|
||||
<hibernate-entitymanager.version>4.3.1.Final</hibernate-entitymanager.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
40
jpa/spring-data-jpa-example/pom.xml
Normal file
40
jpa/spring-data-jpa-example/pom.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-jpa-example</artifactId>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-jpa-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data JPA - Example</name>
|
||||
<description>Small sample project showing the usage of Spring Data JPA.</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.auditing;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import org.springframework.data.domain.Auditable;
|
||||
import org.springframework.data.jpa.domain.AbstractAuditable;
|
||||
|
||||
/**
|
||||
* User domain class that uses auditing functionality of Spring Data that can either be aquired implementing
|
||||
* {@link Auditable} or extend {@link AbstractAuditable}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Entity
|
||||
public class AuditableUser extends AbstractAuditable<AuditableUser, Long> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Set's the user's name.
|
||||
*
|
||||
* @param username the username to set
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user's name.
|
||||
*
|
||||
* @return the username
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.auditing;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface AuditableUserRepository extends CrudRepository<AuditableUser, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.auditing;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableJpaAuditing
|
||||
@EnableJpaRepositories
|
||||
// TODO: Remove once Boot can work with Codd
|
||||
class AuditingConfiguration {
|
||||
|
||||
/**
|
||||
* We need to configure a {@link LocalContainerEntityManagerFactoryBean} manually here as Spring does <em>not</em>
|
||||
* automatically add the {@code orm.xml} <em>if</em> a {@code persistence.xml} is located right beside it. This is
|
||||
* necessary to get the {@link org.springframework.data.jpa.example.repository.basics.BasicFactorySetup} sample
|
||||
* working. However, in a {code persistence.xml}-less codebase you can rely on Spring Boot on setting the correct
|
||||
* defaults.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
|
||||
|
||||
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
|
||||
adapter.setDatabase(Database.HSQL);
|
||||
adapter.setGenerateDdl(true);
|
||||
|
||||
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
|
||||
factoryBean.setPackagesToScan(getClass().getPackage().getName());
|
||||
factoryBean.setMappingResources("META-INF/orm.xml");
|
||||
factoryBean.setJpaVendorAdapter(adapter);
|
||||
factoryBean.setDataSource(dataSource);
|
||||
|
||||
return factoryBean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
AuditorAwareImpl auditorAware() {
|
||||
return new AuditorAwareImpl();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.auditing;
|
||||
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
|
||||
/**
|
||||
* Dummy implementation of {@link AuditorAware}. It will return the configured {@link AuditableUser} as auditor on every
|
||||
* call to {@link #getCurrentAuditor()}. Normally you would access the applications security subsystem to return the
|
||||
* current user.
|
||||
* <p>
|
||||
* TODO: change back to {@code AuditorAware<AuditableUser>} after SD Commons 1.7 RC1 as generic autowiring with Spring 4
|
||||
* will work with that version again.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class AuditorAwareImpl implements AuditorAware<Object> {
|
||||
|
||||
private AuditableUser auditor;
|
||||
|
||||
/**
|
||||
* @param auditor the auditor to set
|
||||
*/
|
||||
public void setAuditor(AuditableUser auditor) {
|
||||
this.auditor = auditor;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.domain.AuditorAware#getCurrentAuditor()
|
||||
*/
|
||||
public AuditableUser getCurrentAuditor() {
|
||||
return auditor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Package showing auditing support with Spring Data repositories.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.auditing;
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.caching;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCache;
|
||||
import org.springframework.cache.support.SimpleCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
/**
|
||||
* Java config to use Spring Data JPA alongside the Spring caching support.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
@EnableAutoConfiguration
|
||||
// TODO: Remove once Boot can work with Codd
|
||||
@EnableJpaRepositories
|
||||
class CachingConfiguration {
|
||||
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
|
||||
Cache cache = new ConcurrentMapCache("byUsername");
|
||||
|
||||
SimpleCacheManager manager = new SimpleCacheManager();
|
||||
manager.setCaches(Arrays.asList(cache));
|
||||
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.caching;
|
||||
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* User repository using Spring's caching abstraction.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public interface CachingUserRepository extends CrudRepository<User, Long> {
|
||||
|
||||
@Override
|
||||
@CacheEvict("byUsername")
|
||||
<S extends User> S save(S entity);
|
||||
|
||||
@Cacheable("byUsername")
|
||||
User findByUsername(String username);
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.caching;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
/**
|
||||
* Sample user class.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Entity
|
||||
@NamedQuery(name = "User.findByTheUsersName", query = "from User u where u.username = ?1")
|
||||
public class User extends AbstractPersistable<Long> {
|
||||
|
||||
private static final long serialVersionUID = -2952735933715107252L;
|
||||
|
||||
@Column(unique = true) private String username;
|
||||
|
||||
private String firstname;
|
||||
private String lastname;
|
||||
|
||||
public User() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user instance.
|
||||
*/
|
||||
public User(Long id) {
|
||||
this.setId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUsername() {
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param username the username to set
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the firstname
|
||||
*/
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param firstname the firstname to set
|
||||
*/
|
||||
public void setFirstname(String firstname) {
|
||||
this.firstname = firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastname
|
||||
*/
|
||||
public String getLastname() {
|
||||
return lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastname the lastname to set
|
||||
*/
|
||||
public void setLastname(String lastname) {
|
||||
this.lastname = lastname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Sample for the integration of the Spring caching abstraction with Spring Data repositories.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.caching;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.custom;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
/**
|
||||
* Sample configuration to bootstrap Spring Data JPA through JavaConfig
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
// TODO: Remove once Boot can work with Codd
|
||||
@EnableJpaRepositories
|
||||
class CustomRepositoryConfig {}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.custom;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
/**
|
||||
* Sample user class.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Entity
|
||||
@NamedQuery(name = "User.findByTheUsersName", query = "from User u where u.username = ?1")
|
||||
public class User extends AbstractPersistable<Long> {
|
||||
|
||||
private static final long serialVersionUID = -2952735933715107252L;
|
||||
|
||||
@Column(unique = true) private String username;
|
||||
|
||||
private String firstname;
|
||||
private String lastname;
|
||||
|
||||
public User() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user instance.
|
||||
*/
|
||||
public User(Long id) {
|
||||
this.setId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUsername() {
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param username the username to set
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the firstname
|
||||
*/
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param firstname the firstname to set
|
||||
*/
|
||||
public void setFirstname(String firstname) {
|
||||
this.firstname = firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastname
|
||||
*/
|
||||
public String getLastname() {
|
||||
return lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastname the lastname to set
|
||||
*/
|
||||
public void setLastname(String lastname) {
|
||||
this.lastname = lastname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.custom;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Repository interface for {@link User} instances. Provides basic CRUD operations due to the extension of
|
||||
* {@link JpaRepository}. Includes custom implemented functionality by extending {@link UserRepositoryCustom}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom {
|
||||
|
||||
/**
|
||||
* Find the user with the given username. This method will be translated into a query using the
|
||||
* {@link javax.persistence.NamedQuery} annotation at the {@link User} class.
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
User findByTheUsersName(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.
|
||||
*
|
||||
* @param lastname
|
||||
* @return
|
||||
*/
|
||||
List<User> findByLastname(String lastname);
|
||||
|
||||
/**
|
||||
* Returns all users with the given firstname. This method will be translated into a query using the one declared in
|
||||
* the {@link Query} annotation declared one.
|
||||
*
|
||||
* @param firstname
|
||||
* @return
|
||||
*/
|
||||
@Query("select u from User u where u.firstname = ?1")
|
||||
List<User> findByFirstname(String firstname);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.custom;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for repository functionality that ought to be implemented manually.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
interface UserRepositoryCustom {
|
||||
|
||||
/**
|
||||
* Custom repository operation.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<User> myCustomBatchOperation();
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.custom;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
|
||||
/**
|
||||
* Implementation fo the custom repository functionality declared in {@link UserRepositoryCustom} based on JPA. To use
|
||||
* this implementation in combination with Spring Data JPA you can either register it programatically:
|
||||
*
|
||||
* <pre>
|
||||
* EntityManager em = ... // Obtain EntityManager
|
||||
*
|
||||
* UserRepositoryCustom custom = new UserRepositoryImpl();
|
||||
* custom.setEntityManager(em);
|
||||
*
|
||||
* RepositoryFactorySupport factory = new JpaRepositoryFactory(em);
|
||||
* UserRepository repository = factory.getRepository(UserRepository.class, custom);
|
||||
* </pre>
|
||||
*
|
||||
* Using the Spring namespace the implementation will just get picked up due to the classpath scanning for
|
||||
* implementations with the {@code Impl} postfix.
|
||||
*
|
||||
* <pre>
|
||||
* <jpa:repositories base-package="com.acme.repository" />
|
||||
* </pre>
|
||||
*
|
||||
* If you need to manually configure the custom instance see {@link UserRepositoryImplJdbc} for an example.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
class UserRepositoryImpl implements UserRepositoryCustom {
|
||||
|
||||
@PersistenceContext private EntityManager em;
|
||||
|
||||
/**
|
||||
* Configure the entity manager to be used.
|
||||
*
|
||||
* @param em the {@link EntityManager} to set.
|
||||
*/
|
||||
public void setEntityManager(EntityManager em) {
|
||||
this.em = em;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.example.repository.UserRepositoryCustom#myCustomBatchOperation()
|
||||
*/
|
||||
public List<User> myCustomBatchOperation() {
|
||||
|
||||
CriteriaQuery<User> criteriaQuery = em.getCriteriaBuilder().createQuery(User.class);
|
||||
criteriaQuery.select(criteriaQuery.from(User.class));
|
||||
return em.createQuery(criteriaQuery).getResultList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.custom;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
|
||||
import org.springframework.jdbc.core.support.JdbcDaoSupport;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Class with the implementation of the custom repository code. Uses JDBC in this case. For basic programatic setup see
|
||||
* {@link UserRepositoryImpl} for examples.
|
||||
* <p>
|
||||
* As you need to hand the instance a {@link javax.sql.DataSource} or
|
||||
* {@link org.springframework.jdbc.core.simple.SimpleJdbcTemplate} you manually need to declare it as Spring bean:
|
||||
*
|
||||
* <pre>
|
||||
* <jpa:repository base-package="com.acme.repository" />
|
||||
*
|
||||
* <bean id="userRepositoryImpl" class="...UserRepositoryJdbcImpl">
|
||||
* <property name="dataSource" ref="dataSource" />
|
||||
* </bean>
|
||||
* </pre>
|
||||
*
|
||||
* Using {@code userRepositoryImpl} will cause the repository instance get this bean injected for custom repository
|
||||
* logic as the default postfix for custom DAO instances is {@code Impl}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Profile("jdbc")
|
||||
@Component("userRepositoryImpl")
|
||||
class UserRepositoryImplJdbc extends JdbcDaoSupport implements UserRepositoryCustom {
|
||||
|
||||
private static final String COMPLICATED_SQL = "SELECT * FROM User";
|
||||
|
||||
@Autowired
|
||||
public UserRepositoryImplJdbc(DataSource dataSource) {
|
||||
setDataSource(dataSource);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.example.repository.UserRepositoryCustom#myCustomBatchOperation()
|
||||
*/
|
||||
public List<User> myCustomBatchOperation() {
|
||||
return getJdbcTemplate().query(COMPLICATED_SQL, new UserRowMapper());
|
||||
}
|
||||
|
||||
private static class UserRowMapper implements ParameterizedRowMapper<User> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int)
|
||||
*/
|
||||
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
|
||||
User user = new User(rs.getLong("id"));
|
||||
user.setUsername(rs.getString("username"));
|
||||
user.setLastname(rs.getString("lastname"));
|
||||
user.setFirstname(rs.getString("firstname"));
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Package showing a repository interface to use basic query method execution functionality as well as <em>customized</em> repository functionality.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.custom;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.simple;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
// TODO: Remove once Boot can work with Codd
|
||||
@EnableJpaRepositories
|
||||
class SimpleConfiguration {}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.simple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public interface SimpleUserRepository extends CrudRepository<User, Long> {
|
||||
|
||||
/**
|
||||
* Find the user with the given username. This method will be translated into a query using the
|
||||
* {@link javax.persistence.NamedQuery} annotation at the {@link User} class.
|
||||
*
|
||||
* @param lastname
|
||||
* @return
|
||||
*/
|
||||
User findByTheUsersName(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.
|
||||
*
|
||||
* @param lastname
|
||||
* @return
|
||||
*/
|
||||
List<User> findByLastname(String lastname);
|
||||
|
||||
/**
|
||||
* Returns all users with the given firstname. This method will be translated into a query using the one declared in
|
||||
* the {@link Query} annotation declared one.
|
||||
*
|
||||
* @param firstname
|
||||
* @return
|
||||
*/
|
||||
@Query("select u from User u where u.firstname = ?")
|
||||
List<User> findByFirstname(String firstname);
|
||||
|
||||
/**
|
||||
* Returns all users with the given name as first- or lastname. Makes use of the {@link Param} annotation to use named
|
||||
* parameters in queries. This makes the query to method relation much more refactoring safe as the order of the
|
||||
* method parameters is completely irrelevant.
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
@Query("select u from User u where u.firstname = :name or u.lastname = :name")
|
||||
List<User> findByFirstnameOrLastname(@Param("name") String name);
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.simple;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
/**
|
||||
* Sample user class.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Entity
|
||||
@NamedQuery(name = "User.findByTheUsersName", query = "from User u where u.username = ?1")
|
||||
public class User extends AbstractPersistable<Long> {
|
||||
|
||||
private static final long serialVersionUID = -2952735933715107252L;
|
||||
|
||||
@Column(unique = true) private String username;
|
||||
|
||||
private String firstname;
|
||||
private String lastname;
|
||||
|
||||
public User() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user instance.
|
||||
*/
|
||||
public User(Long id) {
|
||||
this.setId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUsername() {
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param username the username to set
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the firstname
|
||||
*/
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param firstname the firstname to set
|
||||
*/
|
||||
public void setFirstname(String firstname) {
|
||||
this.firstname = firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastname
|
||||
*/
|
||||
public String getLastname() {
|
||||
return lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastname the lastname to set
|
||||
*/
|
||||
public void setLastname(String lastname) {
|
||||
this.lastname = lastname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Package showing a simple repository interface to use basic query method execution functionality.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.simple;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0">
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
<entity-listeners>
|
||||
<entity-listener class="org.springframework.data.jpa.domain.support.AuditingEntityListener" />
|
||||
</entity-listeners>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata>
|
||||
|
||||
</entity-mappings>
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.auditing;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@Transactional
|
||||
@ContextConfiguration(classes = AuditingConfiguration.class)
|
||||
public class AuditableUserSample {
|
||||
|
||||
@Autowired AuditableUserRepository repository;
|
||||
@Autowired AuditorAwareImpl auditorAware;
|
||||
@Autowired AuditingEntityListener listener;
|
||||
|
||||
@Test
|
||||
public void auditEntityCreation() throws Exception {
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(listener, "handler"), is(notNullValue()));
|
||||
|
||||
AuditableUser user = new AuditableUser();
|
||||
user.setUsername("username");
|
||||
|
||||
auditorAware.setAuditor(user);
|
||||
|
||||
user = repository.save(user);
|
||||
user = repository.save(user);
|
||||
|
||||
assertEquals(user, user.getCreatedBy());
|
||||
assertEquals(user, user.getLastModifiedBy());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.basics;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.jpa.example.repository.simple.SimpleUserRepository;
|
||||
import org.springframework.data.jpa.example.repository.simple.User;
|
||||
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
|
||||
|
||||
/**
|
||||
* Test case showing how to use the basic {@link GenericDaoFactory}
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BasicFactorySetup {
|
||||
|
||||
private static final EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa.sample.plain");
|
||||
|
||||
private SimpleUserRepository userRepository;
|
||||
private EntityManager em;
|
||||
|
||||
private User user;
|
||||
|
||||
/**
|
||||
* Creates a {@link SimpleUserRepository} instance.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
em = factory.createEntityManager();
|
||||
|
||||
userRepository = new JpaRepositoryFactory(em).getRepository(SimpleUserRepository.class);
|
||||
|
||||
em.getTransaction().begin();
|
||||
|
||||
user = new User();
|
||||
user.setUsername("username");
|
||||
user.setFirstname("firstname");
|
||||
user.setLastname("lastname");
|
||||
|
||||
user = userRepository.save(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback transaction.
|
||||
*/
|
||||
@After
|
||||
public void tearDown() {
|
||||
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Showing invocation of finder method.
|
||||
*/
|
||||
@Test
|
||||
public void executingFinders() {
|
||||
|
||||
assertEquals(user, userRepository.findByTheUsersName("username"));
|
||||
assertEquals(user, userRepository.findByLastname("lastname").get(0));
|
||||
assertEquals(user, userRepository.findByFirstname("firstname").get(0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licenseimport static org.junit.Assert.*;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.jpa.example.domain.User;
|
||||
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
ess or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.basics;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.jpa.example.repository.simple.User;
|
||||
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* This unit tests shows plain usage of {@link SimpleJpaRepository}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class BasicSample {
|
||||
|
||||
private CrudRepository<User, Long> userRepository;
|
||||
private EntityManager em;
|
||||
|
||||
/**
|
||||
* Sets up a {@link SimpleJpaRepository} instance.
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa.sample.plain");
|
||||
em = factory.createEntityManager();
|
||||
|
||||
userRepository = new SimpleJpaRepository<User, Long>(User.class, em);
|
||||
|
||||
em.getTransaction().begin();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests saving users. Don't mimic transactionality shown here. It seriously lacks resource cleanup in case of an
|
||||
* exception. Simplification serves descriptivness.
|
||||
*/
|
||||
@Test
|
||||
public void savingUsers() {
|
||||
|
||||
User user = new User();
|
||||
user.setUsername("username");
|
||||
|
||||
user = userRepository.save(user);
|
||||
|
||||
assertEquals(user, userRepository.findOne(user.getId()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.basics;
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.caching;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.Cache.ValueWrapper;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Integration test to show how to use {@link Cacheable} with a Spring Data repository.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@Transactional
|
||||
@ContextConfiguration(classes = CachingConfiguration.class)
|
||||
public abstract class CachingRepositoryTests {
|
||||
|
||||
@Autowired CachingUserRepository repository;
|
||||
@Autowired CacheManager cacheManager;
|
||||
|
||||
@Test
|
||||
public void cachesValuesReturnedForQueryMethod() {
|
||||
|
||||
User dave = new User();
|
||||
dave.setUsername("dmatthews");
|
||||
|
||||
dave = repository.save(dave);
|
||||
|
||||
User result = repository.findByUsername("dmatthews");
|
||||
assertThat(result, is(dave));
|
||||
|
||||
// Verify entity cached
|
||||
Cache cache = cacheManager.getCache("byUsername");
|
||||
ValueWrapper wrapper = cache.get("dmatthews");
|
||||
assertThat(wrapper.get(), is((Object) dave));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.custom;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Intergration test showing the basic usage of {@link UserRepository}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@Transactional
|
||||
@ContextConfiguration(classes = CustomRepositoryConfig.class)
|
||||
// @ActiveProfiles("jdbc") // Uncomment @ActiveProfiles to enable the JDBC Implementation of the custom repository
|
||||
public class UserRepositoryCustomizationTests {
|
||||
|
||||
@Autowired UserRepository repository;
|
||||
|
||||
/**
|
||||
* Tests inserting a user and asserts it can be loaded again.
|
||||
*/
|
||||
@Test
|
||||
public void testInsert() {
|
||||
|
||||
User user = new User();
|
||||
user.setUsername("username");
|
||||
|
||||
user = repository.save(user);
|
||||
|
||||
assertEquals(user, repository.findOne(user.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveAndFindByLastNameAndFindByUserName() {
|
||||
|
||||
User user = new User();
|
||||
user.setUsername("foobar");
|
||||
user.setLastname("lastname");
|
||||
|
||||
user = repository.save(user);
|
||||
|
||||
List<User> users = repository.findByLastname("lastname");
|
||||
|
||||
assertNotNull(users);
|
||||
assertTrue(users.contains(user));
|
||||
|
||||
User reference = repository.findByTheUsersName("foobar");
|
||||
assertEquals(user, reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test invocation of custom method.
|
||||
*/
|
||||
@Test
|
||||
public void testCustomMethod() {
|
||||
|
||||
User user = new User();
|
||||
user.setUsername("username");
|
||||
|
||||
user = repository.save(user);
|
||||
|
||||
List<User> users = repository.myCustomBatchOperation();
|
||||
|
||||
assertNotNull(users);
|
||||
assertTrue(users.contains(user));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.example.repository.simple;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Intergration test showing the basic usage of {@link SimpleUserRepository}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@Transactional
|
||||
@ContextConfiguration(classes = SimpleConfiguration.class)
|
||||
public class SimpleUserRepositoryTests {
|
||||
|
||||
@Autowired SimpleUserRepository repository;
|
||||
User user;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
user = new User();
|
||||
user.setUsername("foobar");
|
||||
user.setFirstname("firstname");
|
||||
user.setLastname("lastname");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findSavedUserById() {
|
||||
|
||||
user = repository.save(user);
|
||||
|
||||
assertEquals(user, repository.findOne(user.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findSavedUserByLastname() throws Exception {
|
||||
|
||||
user = repository.save(user);
|
||||
|
||||
List<User> users = repository.findByLastname("lastname");
|
||||
|
||||
assertNotNull(users);
|
||||
assertTrue(users.contains(user));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByFirstnameOrLastname() throws Exception {
|
||||
|
||||
user = repository.save(user);
|
||||
|
||||
List<User> users = repository.findByFirstnameOrLastname("lastname");
|
||||
|
||||
assertTrue(users.contains(user));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
|
||||
|
||||
<persistence-unit name="jpa.sample.plain">
|
||||
<class>org.springframework.data.jpa.example.repository.simple.User</class>
|
||||
<properties>
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:spring" />
|
||||
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
|
||||
<property name="hibernate.connection.username" value="sa" />
|
||||
<property name="hibernate.connection.password" value="" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
16
jpa/spring-data-jpa-example/src/test/resources/logback.xml
Normal file
16
jpa/spring-data-jpa-example/src/test/resources/logback.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="error" />
|
||||
|
||||
<root level="error">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
16
jpa/spring-data-jpa-interceptors/pom.xml
Normal file
16
jpa/spring-data-jpa-interceptors/pom.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-jpa-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-data-jpa-interceptors</artifactId>
|
||||
<name>Spring Data JPA - Interceptor sample</name>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.spring.data.jpa.sample.interceptors;
|
||||
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
|
||||
import org.springframework.aop.interceptor.CustomizableTraceInterceptor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@Configuration
|
||||
@EnableAspectJAutoProxy
|
||||
@EnableAutoConfiguration
|
||||
// TODO: Remove once Boot can work with Codd
|
||||
@EnableJpaRepositories
|
||||
public class ApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
public CustomizableTraceInterceptor interceptor() {
|
||||
|
||||
CustomizableTraceInterceptor interceptor = new CustomizableTraceInterceptor();
|
||||
interceptor.setEnterMessage("Entering $[methodName]($[arguments]).");
|
||||
interceptor.setExitMessage("Leaving $[methodName](..) with return value $[returnValue], took $[invocationTime]ms.");
|
||||
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Advisor traceAdvisor() {
|
||||
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression("execution(public * org.springframework.data.repository.Repository+.*(..))");
|
||||
|
||||
return new DefaultPointcutAdvisor(pointcut, interceptor());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.spring.data.jpa.sample.interceptors;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
String firstname;
|
||||
String lastname;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.spring.data.jpa.sample.interceptors;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface CustomerRepository extends CrudRepository<Customer, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.spring.data.jpa.sample.interceptors;
|
||||
|
||||
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;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = ApplicationConfiguration.class)
|
||||
public class InterceptorIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
CustomerRepository repository;
|
||||
|
||||
@Test
|
||||
public void foo() {
|
||||
|
||||
Customer customer = new Customer();
|
||||
customer.firstname = "Dave";
|
||||
customer.lastname = "Matthews";
|
||||
|
||||
repository.save(customer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="error" />
|
||||
<logger name="org.springframework.aop.interceptor" level="trace" />
|
||||
|
||||
<root level="error">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
23
jpa/spring-data-jpa-java8-auditing/pom.xml
Normal file
23
jpa/spring-data-jpa-java8-auditing/pom.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-jpa-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-data-jpa-java8-auditing</artifactId>
|
||||
<name>Spring Data JPA - Auditing on Java 8</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.examples.java8;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class AbstractEntity {
|
||||
|
||||
@Id @GeneratedValue Long id;
|
||||
|
||||
@CreatedDate//
|
||||
// @Type(type = "org.jadira.usertype.dateandtime.threetenbp.PersistentZonedDateTime")//
|
||||
ZonedDateTime createdDate;
|
||||
|
||||
@LastModifiedDate//
|
||||
// @Type(type = "org.jadira.usertype.dateandtime.threetenbp.PersistentZonedDateTime")//
|
||||
ZonedDateTime modifiedDate;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.examples.java8;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Entity
|
||||
public class Customer extends AbstractEntity {
|
||||
|
||||
String firstname, lastname;
|
||||
|
||||
public Customer(String firstname, String lastname) {
|
||||
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.examples.java8;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface CustomerRepository extends CrudRepository<Customer, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0">
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
<entity-listeners>
|
||||
<entity-listener class="org.springframework.data.jpa.domain.support.AuditingEntityListener" />
|
||||
</entity-listeners>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata>
|
||||
|
||||
</entity-mappings>
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.examples.java8;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Integration test to show the usage of Java 8 date time APIs with Spring Data JPA auditing.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class Java8AuditingIntegrationTests {
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableJpaRepositories
|
||||
@EnableJpaAuditing
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
@Autowired CustomerRepository repository;
|
||||
|
||||
@Test
|
||||
public void auditingSetsJdk8DateTimeTypes() {
|
||||
|
||||
Customer customer = repository.save(new Customer("Dave", "Matthews"));
|
||||
|
||||
assertThat(customer.createdDate, is(notNullValue()));
|
||||
assertThat(customer.modifiedDate, is(notNullValue()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="info" />
|
||||
<logger name="org.springframework.boot" level="debug" />
|
||||
<logger name="org.hibernate.tool.hbm2ddl" level="trace" />
|
||||
|
||||
<root level="error">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
4
jpa/spring-data-jpa-showcase/README.txt
Normal file
4
jpa/spring-data-jpa-showcase/README.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Spring Data JPA showcase
|
||||
------------------------
|
||||
|
||||
This is the sample app to demo Spring Data JPA features at conferences. The two main packages to take a look at are org.springframework.data.jpa.showcase.before and org.springframework.data.jpa.showcase.after. The first one shows a typical data access implementation with JPA 2. The second one shows what's left if you use Spring Data JPA.
|
||||
62
jpa/spring-data-jpa-showcase/demo.txt
Normal file
62
jpa/spring-data-jpa-showcase/demo.txt
Normal file
@@ -0,0 +1,62 @@
|
||||
1. Introduction
|
||||
---------------
|
||||
- Project structure
|
||||
- Spring configuration
|
||||
- Services
|
||||
- Test cases
|
||||
|
||||
2. Issues
|
||||
---------
|
||||
- Generics, simple queries, pagination (no metadata), is new?, arbitrary queries
|
||||
- Approach: step by step refactoring -> introduce Spring Data JPA
|
||||
|
||||
5. AccountRepository
|
||||
--------------------
|
||||
- replace save(…)
|
||||
- findByCustomer -> show log -> method created from method name
|
||||
- explain proxy mechanism, method signature possibilities (@Param, return types)
|
||||
|
||||
4. Explain general proxy mechanism, SimpleJpaRepository
|
||||
-------------------------------------------------
|
||||
- show JpaRepository interface
|
||||
- findAll(Pageable pageble)
|
||||
|
||||
3. CustomerRepository
|
||||
---------------------
|
||||
- add dependency to CustomerServiceImpl
|
||||
- replace findById, findAll, save
|
||||
- run test
|
||||
- explain extended method signature possibilities (Pageable, Sort)
|
||||
- replace findByLastname(Pageable pageable) in CustomerService
|
||||
|
||||
6. First summary
|
||||
----------------
|
||||
- implementation got obsolete
|
||||
- switch to after package
|
||||
|
||||
7. Querydsl / Specifications
|
||||
----------------------------
|
||||
- Introduce Querydsl
|
||||
- Show Maven setup
|
||||
- Show predicates
|
||||
- Integrate test case
|
||||
|
||||
7. Custom implementation
|
||||
------------------------
|
||||
- copy interface and implementation (hint to visibility)
|
||||
- adapt AccountRepository
|
||||
- copy test case
|
||||
- explain implementation class lookup
|
||||
|
||||
8. JDBC implementation (optional)
|
||||
-----------------------
|
||||
- copy implementation -> configuration necessary
|
||||
- copy XML
|
||||
- run tests -> fail (shows that JDBc bean is used)
|
||||
- fix SQL by adding FROM -> tests run again
|
||||
|
||||
9. Auditing (optional)
|
||||
-----------------------
|
||||
- show auditing test from Hades sample project
|
||||
|
||||
10. Back to slide deck
|
||||
128
jpa/spring-data-jpa-showcase/pom.xml
Normal file
128
jpa/spring-data-jpa-showcase/pom.xml
Normal file
@@ -0,0 +1,128 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-jpa-showcase</artifactId>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-jpa-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data JPA - Refactoring showcase</name>
|
||||
<description>Sample project showing how Spring Data JPA eases implementing repositories over a plain JPA/Spring approach</description>
|
||||
|
||||
<build>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/snippets/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-source</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${basedir}/src/snippets/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add-test-source</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${basedir}/src/test-snippets/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/snippets/**/*.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>querydsl</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-jpa</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>querydsl</id>
|
||||
<name>QueryDsl</name>
|
||||
<url>http://source.mysema.com/maven2/releases</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
<artifactId>apt-maven-plugin</artifactId>
|
||||
<version>${apt.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>process</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target/generated-sources/queries</outputDirectory>
|
||||
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.springframework.data.jpa.showcase.after;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Repository to manage {@link Account} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface AccountRepository extends CrudRepository<Account, Long> {
|
||||
|
||||
/**
|
||||
* Returns all accounts belonging to the given {@link Customer}.
|
||||
*
|
||||
* @param customer
|
||||
* @return
|
||||
*/
|
||||
List<Account> findByCustomer(Customer customer);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.springframework.data.jpa.showcase.after;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Repository to manage {@link Customer} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface CustomerRepository extends CrudRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {
|
||||
|
||||
/**
|
||||
* Returns a page of {@link Customer}s with the given lastname.
|
||||
*
|
||||
* @param lastname
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
Page<Customer> findByLastname(String lastname, Pageable pageable);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.springframework.data.jpa.showcase.before;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
|
||||
/**
|
||||
* Service interface for {@link Account}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface AccountService {
|
||||
|
||||
/**
|
||||
* Saves the given {@link Account}.
|
||||
*
|
||||
* @param account
|
||||
* @return
|
||||
*/
|
||||
Account save(Account account);
|
||||
|
||||
/**
|
||||
* Returns all {@link Account}s of the given {@link Customer}.
|
||||
*
|
||||
* @param customer
|
||||
* @return
|
||||
*/
|
||||
List<Account> findByCustomer(Customer customer);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.springframework.data.jpa.showcase.before;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Plain JPA implementation of {@link AccountService}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Repository
|
||||
@Transactional(readOnly = true)
|
||||
class AccountServiceImpl implements AccountService {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.before.AccountService#save(org.springframework.data.jpa.showcase.core.Account)
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public Account save(Account account) {
|
||||
|
||||
if (account.getId() == null) {
|
||||
em.persist(account);
|
||||
return account;
|
||||
} else {
|
||||
return em.merge(account);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.before.AccountService#findByCustomer(org.springframework.data.jpa.showcase.core.Customer)
|
||||
*/
|
||||
@Override
|
||||
public List<Account> findByCustomer(Customer customer) {
|
||||
|
||||
TypedQuery<Account> query = em.createQuery("select a from Account a where a.customer = ?1", Account.class);
|
||||
query.setParameter(1, customer);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.springframework.data.jpa.showcase.before;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
|
||||
/**
|
||||
* Service interface for {@link Customer}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface CustomerService {
|
||||
|
||||
/**
|
||||
* Returns the {@link Customer} with the given id or {@literal null} if no {@link Customer} with the given id was
|
||||
* found.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Customer findById(Long id);
|
||||
|
||||
/**
|
||||
* Saves the given {@link Customer}.
|
||||
*
|
||||
* @param customer
|
||||
* @return
|
||||
*/
|
||||
Customer save(Customer customer);
|
||||
|
||||
/**
|
||||
* Returns all customers.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Customer> findAll();
|
||||
|
||||
/**
|
||||
* Returns the page of {@link Customer}s with the given index of the given size.
|
||||
*
|
||||
* @param page
|
||||
* @param pageSize
|
||||
* @return
|
||||
*/
|
||||
List<Customer> findAll(int page, int pageSize);
|
||||
|
||||
/**
|
||||
* Returns the page of {@link Customer}s with the given lastname and the given page index and page size.
|
||||
*
|
||||
* @param lastname
|
||||
* @param page
|
||||
* @param pageSize
|
||||
* @return
|
||||
*/
|
||||
List<Customer> findByLastname(String lastname, int page, int pageSize);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package org.springframework.data.jpa.showcase.before;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Plain JPA implementation of {@link CustomerService}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Repository
|
||||
@Transactional(readOnly = true)
|
||||
public class CustomerServiceImpl implements CustomerService {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.before.CustomerService#findById(java.lang.Long)
|
||||
*/
|
||||
@Override
|
||||
public Customer findById(Long id) {
|
||||
return em.find(Customer.class, id);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.before.CustomerService#findAll()
|
||||
*/
|
||||
@Override
|
||||
public List<Customer> findAll() {
|
||||
return em.createQuery("select c from Customer c", Customer.class).getResultList();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.before.CustomerService#findAll(int, int)
|
||||
*/
|
||||
@Override
|
||||
public List<Customer> findAll(int page, int pageSize) {
|
||||
|
||||
TypedQuery<Customer> query = em.createQuery("select c from Customer c", Customer.class);
|
||||
|
||||
query.setFirstResult(page * pageSize);
|
||||
query.setMaxResults(pageSize);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.before.CustomerService#save(org.springframework.data.jpa.showcase.core.Customer)
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public Customer save(Customer customer) {
|
||||
|
||||
// Is new?
|
||||
if (customer.getId() == null) {
|
||||
em.persist(customer);
|
||||
return customer;
|
||||
} else {
|
||||
return em.merge(customer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.before.CustomerService#findByLastname(java.lang.String, int, int)
|
||||
*/
|
||||
@Override
|
||||
public List<Customer> findByLastname(String lastname, int page, int pageSize) {
|
||||
|
||||
TypedQuery<Customer> query = em.createQuery("select c from Customer c where c.lastname = ?1", Customer.class);
|
||||
|
||||
query.setParameter(1, lastname);
|
||||
query.setFirstResult(page * pageSize);
|
||||
query.setMaxResults(pageSize);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.springframework.data.jpa.showcase.core;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Entity
|
||||
public class Account {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ManyToOne
|
||||
private Customer customer;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date expiryDate;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public Date getExpiryDate() {
|
||||
return expiryDate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.data.jpa.showcase.core;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Entity
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String firstname;
|
||||
private String lastname;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
public String getLastname() {
|
||||
return lastname;
|
||||
}
|
||||
}
|
||||
10
jpa/spring-data-jpa-showcase/src/main/resources/data.sql
Normal file
10
jpa/spring-data-jpa-showcase/src/main/resources/data.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
INSERT INTO Customer (id, firstname, lastname) VALUES (1, 'Dave', 'Matthews');
|
||||
INSERT INTO Customer (id, firstname, lastname) VALUES (2, 'Carter', 'Beauford');
|
||||
INSERT INTO Customer (id, firstname, lastname) VALUES (3, 'Stephan', 'Lassard');
|
||||
|
||||
INSERT INTO Account (id, customer_id, expiry_date) VALUES (1, 1, '2010-12-31');
|
||||
INSERT INTO Account (id, customer_id, expiry_date) VALUES (2, 1, '2011-03-31');
|
||||
|
||||
INSERT INTO Customer (id, firstname, lastname) VALUES (4, 'Charly', 'Matthews');
|
||||
INSERT INTO Customer (id, firstname, lastname) VALUES (5, 'Chris', 'Matthews');
|
||||
INSERT INTO Customer (id, firstname, lastname) VALUES (6, 'Paula', 'Matthews');
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.springframework.data.jpa.showcase.snippets;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.core.QAccount;
|
||||
|
||||
import com.mysema.query.types.expr.BooleanExpression;
|
||||
|
||||
/**
|
||||
* Predicates for {@link Account}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AccountPredicates {
|
||||
|
||||
private static QAccount $ = QAccount.account;
|
||||
|
||||
public static BooleanExpression isExpired() {
|
||||
return expiresBefore(new LocalDate());
|
||||
}
|
||||
|
||||
public static BooleanExpression expiresBefore(LocalDate date) {
|
||||
return $.expiryDate.before(date.toDateTimeAtStartOfDay().toDate());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.springframework.data.jpa.showcase.snippets;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.NoRepositoryBean;
|
||||
|
||||
/**
|
||||
* Repository to manage {@link Account} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@NoRepositoryBean
|
||||
public interface AccountRepository extends CrudRepository<Account, Long>, AccountRepositoryCustom,
|
||||
QueryDslPredicateExecutor<Account> {
|
||||
|
||||
/**
|
||||
* Returns all accounts belonging to the given {@link Customer}.
|
||||
*
|
||||
* @param customer
|
||||
* @return
|
||||
*/
|
||||
List<Account> findByCustomer(Customer customer);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.data.jpa.showcase.snippets;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
interface AccountRepositoryCustom {
|
||||
|
||||
void removedExpiredAccounts(LocalDate reference);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.springframework.data.jpa.showcase.snippets;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Repository
|
||||
class AccountRepositoryImpl implements AccountRepositoryCustom {
|
||||
|
||||
@PersistenceContext private EntityManager em;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.snippets.AccountRepositoryCustom#removedExpiredAccounts(org.joda.time.LocalDate)
|
||||
*/
|
||||
@Override
|
||||
public void removedExpiredAccounts(LocalDate reference) {
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<Account> query = cb.createQuery(Account.class);
|
||||
Root<Account> account = query.from(Account.class);
|
||||
|
||||
query.where(cb.lessThan(account.get("expiryDate").as(Date.class), reference.toDateTimeAtStartOfDay().toDate()));
|
||||
|
||||
for (Account each : em.createQuery(query).getResultList()) {
|
||||
em.remove(each);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.springframework.data.jpa.showcase.snippets;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Repository
|
||||
class AccountRepositoryJdbcImpl implements AccountRepositoryCustom {
|
||||
|
||||
private JdbcTemplate template;
|
||||
|
||||
public void setTemplate(JdbcTemplate template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.showcase.snippets.AccountRepositoryCustom#removedExpiredAccounts(org.joda.time.LocalDate)
|
||||
*/
|
||||
@Override
|
||||
public void removedExpiredAccounts(LocalDate reference) {
|
||||
template.update("DELETE Account AS a WHERE a.expiryDate < ?", reference.toDateTimeAtStartOfDay().toDate());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.springframework.data.jpa.showcase.snippets;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
|
||||
/**
|
||||
* Collection of {@link Specification} implementations.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class CustomerSpecifications {
|
||||
|
||||
/**
|
||||
* All customers with an {@link Account} expiring before the given date.
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static Specification<Customer> accountExpiresBefore(final LocalDate date) {
|
||||
|
||||
return new Specification<Customer>() {
|
||||
|
||||
@Override
|
||||
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
|
||||
|
||||
Root<Account> accounts = query.from(Account.class);
|
||||
Path<Date> expiryDate = accounts.<Date> get("expiryDate");
|
||||
Predicate customerIsAccountOwner = cb.equal(accounts.<Customer> get("customer"), root);
|
||||
Predicate accountExpiryDateBefore = cb.lessThan(expiryDate, date.toDateTimeAtStartOfDay().toDate());
|
||||
|
||||
return cb.and(customerIsAccountOwner, accountExpiryDateBefore);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<bean id="accountDaoImpl" class="org.springframework.data.jpa.showcase.after.AccountDaoJdbcImpl">
|
||||
<property name="template">
|
||||
<bean class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.springframework.data.jpa.showcase.snippets.test;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.jpa.showcase.snippets.AccountPredicates.*;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.snippets.AccountRepository;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class AccountRepositoryIntegrationTest {
|
||||
|
||||
private AccountRepository accountRepository;
|
||||
|
||||
public void removesExpiredAccountsCorrectly() throws Exception {
|
||||
|
||||
accountRepository.removedExpiredAccounts(new LocalDate(2011, 1, 1));
|
||||
assertThat(accountRepository.count(), is(1L));
|
||||
}
|
||||
|
||||
public void findsExpiredAccounts() {
|
||||
|
||||
Account expired = accountRepository.findOne(1L);
|
||||
Account valid = accountRepository.findOne(2L);
|
||||
|
||||
Iterable<Account> findAll = accountRepository.findAll(expiresBefore(new LocalDate(2011, 3, 1)));
|
||||
|
||||
assertThat(findAll, hasItem(expired));
|
||||
assertThat(findAll, not(hasItem(valid)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.springframework.data.jpa.showcase.snippets.test;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.jpa.domain.Specifications.*;
|
||||
import static org.springframework.data.jpa.showcase.snippets.CustomerSpecifications.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.showcase.after.CustomerRepository;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
|
||||
/**
|
||||
* Snippets to show the usage of {@link Specification}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class CustomerRepositoryIntegrationTest {
|
||||
|
||||
private CustomerRepository repository;
|
||||
|
||||
public void findsCustomersBySpecification() throws Exception {
|
||||
|
||||
Customer dave = repository.findOne(1L);
|
||||
|
||||
LocalDate expiryLimit = new LocalDate(2011, 3, 1);
|
||||
List<Customer> result = repository.findAll(where(accountExpiresBefore(expiryLimit)));
|
||||
|
||||
assertThat(result.size(), is(1));
|
||||
assertThat(result, hasItems(dave));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.springframework.data.jpa.showcase;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.data.jpa.showcase.AbstractShowcaseTest.TestConfig;
|
||||
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
|
||||
import org.springframework.test.context.transaction.BeforeTransaction;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SpringApplicationConfiguration(classes = TestConfig.class)
|
||||
@Transactional
|
||||
public abstract class AbstractShowcaseTest extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
// TODO: Remove once Boot can work with Codd
|
||||
@EnableJpaRepositories
|
||||
@ComponentScan
|
||||
static class TestConfig {
|
||||
|
||||
}
|
||||
|
||||
@BeforeTransaction
|
||||
public void setupData() throws Exception {
|
||||
|
||||
deleteFromTables("account", "customer");
|
||||
executeSqlScript("classpath:data.sql", false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.showcase.after;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.showcase.AbstractShowcaseTest;
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
|
||||
/**
|
||||
* Integration tests for Spring Data JPA {@link AccountRepository}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AccountRepositoryIntegrationTest extends AbstractShowcaseTest {
|
||||
|
||||
@Autowired AccountRepository accountRepository;
|
||||
@Autowired CustomerRepository customerRepository;
|
||||
|
||||
@Test
|
||||
public void savesAccount() {
|
||||
|
||||
Account account = accountRepository.save(new Account());
|
||||
assertThat(account.getId(), is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsCustomersAccounts() {
|
||||
|
||||
Customer customer = customerRepository.findOne(1L);
|
||||
List<Account> accounts = accountRepository.findByCustomer(customer);
|
||||
|
||||
assertFalse(accounts.isEmpty());
|
||||
assertThat(accounts.get(0).getCustomer(), is(customer));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.showcase.after;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.jpa.domain.Specifications.*;
|
||||
import static org.springframework.data.jpa.showcase.snippets.CustomerSpecifications.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.showcase.AbstractShowcaseTest;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
|
||||
/**
|
||||
* Integration tests for Spring Data JPA {@link CustomerRepository}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class CustomerRepositoryIntegrationTest extends AbstractShowcaseTest {
|
||||
|
||||
@Autowired CustomerRepository repository;
|
||||
|
||||
@Test
|
||||
public void findsAllCustomers() throws Exception {
|
||||
|
||||
Iterable<Customer> result = repository.findAll();
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertTrue(result.iterator().hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsFirstPageOfMatthews() throws Exception {
|
||||
|
||||
Page<Customer> customers = repository.findByLastname("Matthews", new PageRequest(0, 2));
|
||||
|
||||
assertThat(customers.getContent().size(), is(2));
|
||||
assertFalse(customers.hasPreviousPage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsCustomerById() throws Exception {
|
||||
|
||||
Customer customer = repository.findOne(2L);
|
||||
|
||||
assertThat(customer.getFirstname(), is("Carter"));
|
||||
assertThat(customer.getLastname(), is("Beauford"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsCustomersBySpecification() throws Exception {
|
||||
|
||||
Customer dave = repository.findOne(1L);
|
||||
|
||||
LocalDate expiryLimit = new LocalDate(2011, 3, 1);
|
||||
List<Customer> result = repository.findAll(where(accountExpiresBefore(expiryLimit)));
|
||||
|
||||
assertThat(result.size(), is(1));
|
||||
assertThat(result, hasItems(dave));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.showcase.before;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.showcase.AbstractShowcaseTest;
|
||||
import org.springframework.data.jpa.showcase.core.Account;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
|
||||
/**
|
||||
* Integration test for {@link AccountService}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AccountServiceIntegrationTest extends AbstractShowcaseTest {
|
||||
|
||||
@Autowired AccountService accountService;
|
||||
@Autowired CustomerService customerService;
|
||||
|
||||
@Test
|
||||
public void savesAccount() {
|
||||
|
||||
Account account = accountService.save(new Account());
|
||||
assertThat(account.getId(), is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testname() throws Exception {
|
||||
|
||||
Customer customer = customerService.findById(1L);
|
||||
|
||||
List<Account> accounts = accountService.findByCustomer(customer);
|
||||
|
||||
assertThat(accounts, is(not(empty())));
|
||||
assertThat(accounts.get(0).getCustomer(), is(customer));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.jpa.showcase.before;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.showcase.AbstractShowcaseTest;
|
||||
import org.springframework.data.jpa.showcase.core.Customer;
|
||||
|
||||
/**
|
||||
* Integration test for {@link CustomerService}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class CustomerServiceIntegrationTest extends AbstractShowcaseTest {
|
||||
|
||||
@Autowired CustomerService repository;
|
||||
|
||||
@Test
|
||||
public void findsAllCustomers() throws Exception {
|
||||
|
||||
List<Customer> result = repository.findAll();
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertFalse(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsPageOfMatthews() throws Exception {
|
||||
|
||||
List<Customer> customers = repository.findByLastname("Matthews", 0, 2);
|
||||
|
||||
assertThat(customers.size(), is(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsCustomerById() throws Exception {
|
||||
|
||||
Customer customer = repository.findById(2L);
|
||||
|
||||
assertThat(customer.getFirstname(), is("Carter"));
|
||||
assertThat(customer.getLastname(), is("Beauford"));
|
||||
}
|
||||
}
|
||||
16
jpa/spring-data-jpa-showcase/src/test/resources/logback.xml
Normal file
16
jpa/spring-data-jpa-showcase/src/test/resources/logback.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.data" level="debug" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
70
mongodb/pom.xml
Normal file
70
mongodb/pom.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-mongodb-example</artifactId>
|
||||
|
||||
<name>Spring Data MongoDB - Example</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<spring-data-mongo.version>1.4.0.DATAMONGO-838-SNAPSHOT</spring-data-mongo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-mongodb</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
<artifactId>apt-maven-plugin</artifactId>
|
||||
<version>${apt.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>process</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target/generated-sources/annotations</outputDirectory>
|
||||
<processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<url>http://repo.spring.io/libs-snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.customer;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
|
||||
/**
|
||||
* A domain object to capture addresses.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class Address {
|
||||
|
||||
private final Point location;
|
||||
private String street;
|
||||
private String zipCode;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.customer;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An entity to represent a customer.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Data
|
||||
@Document
|
||||
public class Customer {
|
||||
|
||||
private ObjectId id;
|
||||
private String firstname, lastname;
|
||||
|
||||
@GeoSpatialIndexed(name = "address.location")//
|
||||
private Address address;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Customer} with the given firstname and lastname.
|
||||
*
|
||||
* @param firstname must not be {@literal null} or empty.
|
||||
* @param lastname must not be {@literal null} or empty.
|
||||
*/
|
||||
public Customer(String firstname, String lastname) {
|
||||
|
||||
Assert.hasText(firstname, "Firstname must not be null or empty!");
|
||||
Assert.hasText(lastname, "Lastname must not be null or empty!");
|
||||
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.customer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Repository interface to manage {@link Customer} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface CustomerRepository extends CrudRepository<Customer, ObjectId> {
|
||||
|
||||
/**
|
||||
* Derived query using dynamic sort information.
|
||||
*
|
||||
* @param lastname
|
||||
* @param sort
|
||||
* @return
|
||||
*/
|
||||
List<Customer> findByLastname(String lastname, Sort sort);
|
||||
|
||||
/**
|
||||
* Showcase for a repository query using geo-spatial functionality.
|
||||
*
|
||||
* @param point
|
||||
* @param distance
|
||||
* @return
|
||||
*/
|
||||
GeoResults<Customer> findByAddressLocationNear(Point point, Distance distance);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.shop;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
/**
|
||||
* A DTO to represent invoices.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Value
|
||||
public class Invoice {
|
||||
|
||||
private final String orderId;
|
||||
private final double taxAmount;
|
||||
private final double netAmount;
|
||||
private final double totalAmount;
|
||||
private final List<LineItem> items;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.shop;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
|
||||
/**
|
||||
* A line item.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Data
|
||||
@RequiredArgsConstructor(onConstructor = @__(@PersistenceConstructor))
|
||||
public class LineItem {
|
||||
|
||||
private final String caption;
|
||||
private final double price;
|
||||
|
||||
int quantity = 1;
|
||||
|
||||
public LineItem(String caption, double price, int quantity) {
|
||||
|
||||
this(caption, price);
|
||||
this.quantity = quantity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.shop;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
/**
|
||||
* An entity representing an {@link Order}. Note how we don't need any MongoDB mapping annotations as {@code id} is
|
||||
* recognized as the id property by default.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Data
|
||||
@RequiredArgsConstructor(onConstructor = @__(@PersistenceConstructor))
|
||||
@Document
|
||||
public class Order {
|
||||
|
||||
private final String id;
|
||||
private final String customerId;
|
||||
private final Date orderDate;
|
||||
private final List<LineItem> items;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Order} for the given customer id and order date.
|
||||
*
|
||||
* @param customerId
|
||||
* @param orderDate
|
||||
*/
|
||||
public Order(String customerId, Date orderDate) {
|
||||
this(null, customerId, orderDate, new ArrayList<LineItem>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link LineItem} to the {@link Order}.
|
||||
*
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public Order addItem(LineItem item) {
|
||||
|
||||
this.items.add(item);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.shop;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* A repository interface assembling CRUD functionality as well as the API to invoke the methods implemented manually.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface OrderRepository extends CrudRepository<Order, String>, OrderRepositoryCustom {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.shop;
|
||||
|
||||
/**
|
||||
* The interface for repository functionality that will be implemented manually.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
interface OrderRepositoryCustom {
|
||||
|
||||
/**
|
||||
* Creates an {@link Invoice} for the given {@link Order}.
|
||||
*
|
||||
* @param order must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
Invoice getInvoiceFor(Order order);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.shop;
|
||||
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||
|
||||
/**
|
||||
* The manual implementation parts for {@link OrderRepository}. This will automatically be picked up by the Spring Data
|
||||
* infrastructure as we follow the naming convention of extending the core repository interface's name with {@code Impl}
|
||||
* .
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
class OrderRepositoryImpl implements OrderRepositoryCustom {
|
||||
|
||||
private MongoOperations operations;
|
||||
|
||||
private double taxRate = 0.19;
|
||||
|
||||
/**
|
||||
* The implementation uses the MongoDB aggregation framework support Spring Data provides as well as SpEL expressions
|
||||
* to define arithmetical expressions. Note how we work with property names only and don't have to mitigate the nested
|
||||
* {@code $_id} fields MongoDB usually requires.
|
||||
*
|
||||
* @see org.springframework.data.examples.mongodb.shop.OrderRepositoryCustom#getInvoiceFor(org.springframework.data.examples.mongodb.shop.Order)
|
||||
*/
|
||||
@Override
|
||||
public Invoice getInvoiceFor(Order order) {
|
||||
|
||||
AggregationResults<Invoice> results = operations.aggregate(newAggregation(Order.class, //
|
||||
match(where("id").is(order.getId())), //
|
||||
unwind("items"), //
|
||||
project("id", "customerId", "items") //
|
||||
.andExpression("'$items.price' * '$items.quantity'").as("lineTotal"), //
|
||||
group("id") //
|
||||
.sum("lineTotal").as("netAmount") //
|
||||
.addToSet("items").as("items"), //
|
||||
project("id", "items", "netAmount") //
|
||||
.and("orderId").previousOperation() //
|
||||
.andExpression("netAmount * [0]", taxRate).as("taxAmount") //
|
||||
.andExpression("netAmount * (1 + [0])", taxRate).as("totalAmount") //
|
||||
), Invoice.class);
|
||||
|
||||
return results.getUniqueMappedResult();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* Test configuration to connect to a MongoDB named "test" and using a {@link MongoClient}. Also enables Spring Data
|
||||
* repositories for MongoDB.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
public class TestConfiguration extends AbstractMongoConfiguration {
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mongo mongo() throws Exception {
|
||||
return new MongoClient();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.customer;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.examples.mongodb.TestConfiguration;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.geo.Metrics;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.querydsl.QSort;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Integration test for {@link CustomerRepository}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = TestConfiguration.class)
|
||||
public class CustomerRepositoryIntegrationTest {
|
||||
|
||||
@Autowired CustomerRepository repository;
|
||||
|
||||
Customer dave, oliver, carter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
repository.deleteAll();
|
||||
|
||||
dave = repository.save(new Customer("Dave", "Matthews"));
|
||||
oliver = repository.save(new Customer("Oliver August", "Matthews"));
|
||||
carter = repository.save(new Customer("Carter", "Beauford"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case to show that automatically generated ids are assigned to the domain objects.
|
||||
*/
|
||||
@Test
|
||||
public void setsIdOnSave() {
|
||||
|
||||
Customer dave = repository.save(new Customer("Dave", "Matthews"));
|
||||
assertThat(dave.getId(), is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case to show the usage of the Querydsl-specific {@link QSort} to define the sort order in a type-safe way.
|
||||
*/
|
||||
@Test
|
||||
public void findCustomersUsingQuerydslSort() {
|
||||
|
||||
QCustomer customer = QCustomer.customer;
|
||||
List<Customer> result = repository.findByLastname("Matthews", new QSort(customer.firstname.asc()));
|
||||
|
||||
assertThat(result, hasSize(2));
|
||||
assertThat(result.get(0), is(dave));
|
||||
assertThat(result.get(1), is(oliver));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case to show the usage of the geo-spatial APIs to lookup people within a given distance of a reference point.
|
||||
*/
|
||||
@Test
|
||||
public void exposesGeoSpatialFunctionality() {
|
||||
|
||||
Customer ollie = new Customer("Oliver", "Gierke");
|
||||
ollie.setAddress(new Address(new Point(52.52548, 13.41477)));
|
||||
ollie = repository.save(ollie);
|
||||
|
||||
Point referenceLocation = new Point(52.51790, 13.41239);
|
||||
Distance oneKilometer = new Distance(1, Metrics.KILOMETERS);
|
||||
|
||||
GeoResults<Customer> result = repository.findByAddressLocationNear(referenceLocation, oneKilometer);
|
||||
|
||||
assertThat(result.getContent(), hasSize(1));
|
||||
assertThat(result.getContent().get(0).getDistance(), is(new Distance(0.8624842788060683, Metrics.KILOMETERS)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
package org.springframework.data.examples.mongodb.shop;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.number.IsCloseTo.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.examples.mongodb.TestConfiguration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link OrderRepository}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = TestConfiguration.class)
|
||||
public class OrderRepositoryIntegrationTests {
|
||||
|
||||
@Autowired OrderRepository repository;
|
||||
|
||||
private final static LineItem product1 = new LineItem("p1", 1.23);
|
||||
private final static LineItem product2 = new LineItem("p2", 0.87, 2);
|
||||
private final static LineItem product3 = new LineItem("p3", 5.33);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
repository.deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createsInvoiceViaAggregation() {
|
||||
|
||||
Order order = new Order("c42", new Date()).//
|
||||
addItem(product1).addItem(product2).addItem(product3);
|
||||
order = repository.save(order);
|
||||
|
||||
Invoice invoice = repository.getInvoiceFor(order);
|
||||
|
||||
assertThat(invoice, is(notNullValue()));
|
||||
assertThat(invoice.getOrderId(), is(order.getId()));
|
||||
assertThat(invoice.getNetAmount(), is(closeTo(8.3, 000001)));
|
||||
assertThat(invoice.getTaxAmount(), is(closeTo(1.577, 000001)));
|
||||
assertThat(invoice.getTotalAmount(), is(closeTo(9.877, 000001)));
|
||||
}
|
||||
}
|
||||
17
mongodb/src/test/resources/logback.xml
Normal file
17
mongodb/src/test/resources/logback.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.data.mongodb" level="debug" />
|
||||
<logger name="org.springframework.data.mongodb.core.aggregation" level="debug" />
|
||||
|
||||
<root level="error">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
86
pom.xml
Normal file
86
pom.xml
Normal file
@@ -0,0 +1,86 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data - Examples</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.0.0.RC1</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>jpa</module>
|
||||
<module>mongodb</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
||||
<spring.version>4.0.1.RELEASE</spring.version>
|
||||
<querydsl.version>3.3.0</querydsl.version>
|
||||
<apt.version>1.1.1</apt.version>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
</properties>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke@gopivotal.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>tdarimont</id>
|
||||
<name>Thomas Darimont</name>
|
||||
<email>tdarimont@gopivotal.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.12.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-milestone</id>
|
||||
<url>http://repo.spring.io/libs-milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
Reference in New Issue
Block a user