Add a plain JPA sample application

Closes gh-1761
This commit is contained in:
Andy Wilkinson 2014-11-25 10:19:28 +00:00
parent 4402c6b4a0
commit 6d97785030
15 changed files with 604 additions and 0 deletions

View File

@ -44,6 +44,7 @@
<module>spring-boot-sample-jetty-ssl</module>
<module>spring-boot-sample-jetty8</module>
<module>spring-boot-sample-jetty8-ssl</module>
<module>spring-boot-sample-jpa</module>
<module>spring-boot-sample-jta-atomikos</module>
<module>spring-boot-sample-jta-bitronix</module>
<module>spring-boot-sample-jta-jndi</module>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>1.2.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-jpa</artifactId>
<name>Spring Boot JPA Sample</name>
<description>Spring Boot JPA Sample</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,29 @@
/*
* 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 sample.jpa;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SampleJpaApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleJpaApplication.class, args);
}
}

View File

@ -0,0 +1,73 @@
/*
* 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 sample.jpa.domain;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
@Entity
public class Note {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String title;
private String body;
@ManyToMany
private List<Tag> tags;
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return this.body;
}
public void setBody(String body) {
this.body = body;
}
public List<Tag> getTags() {
return this.tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
}

View File

@ -0,0 +1,63 @@
/*
* 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 sample.jpa.domain;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
@Entity
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@ManyToMany(mappedBy = "tags")
private List<Note> notes;
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public List<Note> getNotes() {
return this.notes;
}
public void setNotes(List<Note> notes) {
this.notes = notes;
}
}

View File

@ -0,0 +1,40 @@
/*
* 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 sample.jpa.repository;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import sample.jpa.domain.Note;
@Repository
class JpaNoteRepository implements NoteRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
public List<Note> findAll() {
return this.entityManager.createQuery("SELECT n FROM Note n", Note.class)
.getResultList();
}
}

View File

@ -0,0 +1,40 @@
/*
* 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 sample.jpa.repository;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import sample.jpa.domain.Tag;
@Repository
class JpaTagRepository implements TagRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
public List<Tag> findAll() {
return this.entityManager.createQuery("SELECT t FROM Tag t", Tag.class)
.getResultList();
}
}

View File

@ -0,0 +1,27 @@
/*
* 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 sample.jpa.repository;
import java.util.List;
import sample.jpa.domain.Note;
public interface NoteRepository {
List<Note> findAll();
}

View File

@ -0,0 +1,27 @@
/*
* 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 sample.jpa.repository;
import java.util.List;
import sample.jpa.domain.Tag;
public interface TagRepository {
List<Tag> findAll();
}

View File

@ -0,0 +1,45 @@
/*
* 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 sample.jpa.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import sample.jpa.domain.Note;
import sample.jpa.repository.NoteRepository;
@Controller
public class IndexController {
@Autowired
private NoteRepository noteRepository;
@RequestMapping("/")
@Transactional(readOnly = true)
public ModelAndView index() {
List<Note> notes = this.noteRepository.findAll();
ModelAndView modelAndView = new ModelAndView("index");
modelAndView.addObject("notes", notes);
return modelAndView;
}
}

View File

@ -0,0 +1,17 @@
insert into tag(name) values ('Spring projects')
insert into tag(name) values ('Apache projects')
insert into tag(name) values ('Open source')
insert into note(title, body) values ('Spring Boot', 'Takes an opinionated view of building production-ready Spring applications.')
insert into note(title, body) values ('Spring Framework', 'Core support for dependency injection, transaction management, web applications, data access, messaging, testing and more.')
insert into note(title, body) values ('Spring Integration', 'Extends the Spring programming model to support the well-known Enterprise Integration Patterns.')
insert into note(title, body) values ('Tomcat', 'Apache Tomcat is an open source software implementation of the Java Servlet and JavaServer Pages technologies.')
insert into note_tags(notes_id, tags_id) values (1, 1)
insert into note_tags(notes_id, tags_id) values (2, 1)
insert into note_tags(notes_id, tags_id) values (3, 1)
insert into note_tags(notes_id, tags_id) values (1, 3)
insert into note_tags(notes_id, tags_id) values (2, 3)
insert into note_tags(notes_id, tags_id) values (3, 3)
insert into note_tags(notes_id, tags_id) values (4, 2)
insert into note_tags(notes_id, tags_id) values (4, 3)

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<body>
<table>
<thead>
<tr>
<td>Title</td>
<td>Body</td>
<td>Tags</td>
</tr>
</thead>
<tbody>
<#list notes as note>
<tr>
<td>${note.title}</td>
<td>${note.body}</td>
<td>
<#list note.tags as tag>
<span>${tag.name}</span>
</#list>
</td>
</tr>
</#list>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,61 @@
/*
* 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 sample.jpa;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath;
/**
* Integration test to run the application.
*
* @author Oliver Gierke
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleJpaApplication.class)
@WebAppConfiguration
public class SampleJpaApplicationTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before
public void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
@Test
public void testHome() throws Exception {
this.mvc.perform(get("/")).andExpect(status().isOk())
.andExpect(xpath("//tbody/tr").nodeCount(4));
}
}

View File

@ -0,0 +1,49 @@
/*
* 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 sample.jpa.repository;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.jpa.SampleJpaApplication;
import sample.jpa.domain.Note;
import static org.junit.Assert.assertEquals;
/**
* Integration tests for {@link JpaNoteRepository}.
*
* @author Andy Wilkinson
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleJpaApplication.class)
public class JpaNoteRepositoryIntegrationTests {
@Autowired
JpaNoteRepository repository;
@Test
public void findsAllNotes() {
List<Note> notes = this.repository.findAll();
assertEquals(4, notes.size());
}
}

View File

@ -0,0 +1,49 @@
/*
* 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 sample.jpa.repository;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.jpa.SampleJpaApplication;
import sample.jpa.domain.Tag;
import static org.junit.Assert.assertEquals;
/**
* Integration tests for {@link JpaTagRepository}.
*
* @author Andy Wilkinson
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleJpaApplication.class)
public class JpaTagRepositoryIntegrationTests {
@Autowired
JpaTagRepository repository;
@Test
public void findsAllTags() {
List<Tag> tags = this.repository.findAll();
assertEquals(3, tags.size());
}
}