Even though it wasn't difficult, there was a main disadvantage - we need to do a lot of coding around our DAO objects even if we want only simple operations.
Spring Data JPA helps us reduce data access coding.
Let's start with defining dependencies:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dependency> | |
<groupId>org.springframework.data</groupId> | |
<artifactId>spring-data-jpa</artifactId> | |
<version>1.1.0.RELEASE</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-jdbc</artifactId> | |
<version>3.2.0.RELEASE</version> | |
</dependency> | |
<dependency> | |
<groupId>org.hibernate</groupId> | |
<artifactId>hibernate-entitymanager</artifactId> | |
<version>4.1.9.Final</version> | |
</dependency> | |
<dependency> | |
<groupId>org.hsqldb</groupId> | |
<artifactId>hsqldb</artifactId> | |
<version>2.2.9</version> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.11</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.hamcrest</groupId> | |
<artifactId>hamcrest-all</artifactId> | |
<version>1.3</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-test</artifactId> | |
<version>3.2.0.RELEASE</version> | |
<scope>test</scope> | |
</dependency> |
pesistence.xml is much smaller because the persistence configuration will be defined in spring context.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<persistence 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" version="2.0"> | |
<persistence-unit name="springJpaPersistenceUnit" transaction-type="RESOURCE_LOCAL"> | |
<provider>org.hibernate.ejb.HibernatePersistence</provider> | |
<class>pl.mjedynak.model.Person</class> | |
<properties> | |
<property name="hibernate.hbm2ddl.auto" value="create"/> | |
</properties> | |
</persistence-unit> | |
</persistence> |
The context is defined as:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:context="http://www.springframework.org/schema/context" | |
xmlns:jpa="http://www.springframework.org/schema/data/jpa" | |
xsi:schemaLocation=" | |
http://www.springframework.org/schema/beans | |
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd | |
http://www.springframework.org/schema/context | |
http://www.springframework.org/schema/context/spring-context-3.2.xsd | |
http://www.springframework.org/schema/data/jpa | |
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> | |
<context:component-scan base-package="pl.mjedynak"/> | |
<jpa:repositories base-package="pl.mjedynak.repository"/> | |
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> | |
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/> | |
<property name="url" value="jdbc:hsqldb:file:sampledb"/> | |
<property name="username" value="sa"/> | |
<property name="password" value=""/> | |
</bean> | |
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> | |
<property name="dataSource" ref="dataSource"/> | |
<property name="persistenceXmlLocation" value="persistence.xml"/> | |
<property name="persistenceUnitName" value="springJpaPersistenceUnit"/> | |
</bean> | |
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> | |
<property name="entityManagerFactory" ref="entityManagerFactory"/> | |
</bean> | |
</beans> |
The pl.mjedynak package will be scanned by spring to do autowiring.
Spring Data JPA introduces the concept of repository which is higher level of abstraction than the DAO.
In our context we define a package with the repositories.
The only thing to do to be able to manage our Person class is to create an interface that will extend CrudRepository - it gives us basic operations like save, find, delete etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface PersonRepository extends CrudRepository<Person, Long> { | |
} |
The integration test is almost the same as before, except it needs to use spring context.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RunWith(SpringJUnit4ClassRunner.class) | |
@ContextConfiguration(locations = "classpath:spring-context.xml") | |
public class PersonRepositoryIntegrationTest { | |
@Autowired | |
private PersonRepository personRepository; | |
@Test | |
public void shouldFindPreviouslySavedPerson() { | |
// given | |
Integer age = 22; | |
String name = "Charlie"; | |
Person person = aPerson(). | |
withAge(age). | |
withName(name).build(); | |
personRepository.save(person); | |
// when | |
List<Person> result = (List<Person>) personRepository.findAll(); | |
// then | |
assertThat(result, hasSize(1)); | |
Person foundPerson = result.get(0); | |
assertThat(foundPerson.getAge(), is(age)); | |
assertThat(foundPerson.getName(), is(name)); | |
} | |
} |
The whole project can be found at: https://github.com/mjedynak/spring-data-jpa-example
Mike, your example compiles using
ReplyDeletemvn clean package
I am new to Spring Data and I will highly appreciate if you can help how to execute this under tomcat or stand alone.
It is just a matter of changing your spring context configuration in your existing project by adding the beans defined above.
ReplyDeleteIf you're looking for a way to simply create executable project, I'd suggest trying:
http://spring.io/guides/gs/spring-boot/
or even checking spring boot data jpa sample project:
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-data-jpa
Thanks Michael for blogging about your approach accessing MarkLogic server via a repository-style interface, I felt inspired and integrated it with Spring Boot over at: https://github.com/nikos/springboot-marklogic-sample/
ReplyDeleteCheers, Niko