{"action":"closed","issue":{"url":"https://api.github.com/repos/Hanope/spring-guides/issues/16","repository_url":"https://api.github.com/repos/Hanope/spring-guides","labels_url":"https://api.github.com/repos/Hanope/spring-guides/issues/16/labels{/name}","comments_url":"https://api.github.com/repos/Hanope/spring-guides/issues/16/comments","events_url":"https://api.github.com/repos/Hanope/spring-guides/issues/16/events","html_url":"https://github.com/Hanope/spring-guides/issues/16","id":378981690,"node_id":"MDU6SXNzdWUzNzg5ODE2OTA=","number":16,"title":"Accessing Data with JPA (gs-accessing-data-jpa)","user":{"login":"Hanope","id":19226330,"node_id":"MDQ6VXNlcjE5MjI2MzMw","avatar_url":"https://avatars1.githubusercontent.com/u/19226330?v=4","gravatar_id":"","url":"https://api.github.com/users/Hanope","html_url":"https://github.com/Hanope","followers_url":"https://api.github.com/users/Hanope/followers","following_url":"https://api.github.com/users/Hanope/following{/other_user}","gists_url":"https://api.github.com/users/Hanope/gists{/gist_id}","starred_url":"https://api.github.com/users/Hanope/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hanope/subscriptions","organizations_url":"https://api.github.com/users/Hanope/orgs","repos_url":"https://api.github.com/users/Hanope/repos","events_url":"https://api.github.com/users/Hanope/events{/privacy}","received_events_url":"https://api.github.com/users/Hanope/received_events","type":"User","site_admin":false},"labels":[{"id":1129571503,"node_id":"MDU6TGFiZWwxMTI5NTcxNTAz","url":"https://api.github.com/repos/Hanope/spring-guides/labels/complete","name":"complete","color":"0052cc","default":false},{"id":1119488097,"node_id":"MDU6TGFiZWwxMTE5NDg4MDk3","url":"https://api.github.com/repos/Hanope/spring-guides/labels/translation","name":"translation","color":"0e8a16","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-11-09T01:03:23Z","updated_at":"2018-11-30T11:46:28Z","closed_at":"2018-11-30T11:46:28Z","author_association":"OWNER","body":"## Accessing Data with JPA\r\nThis guide walks you through the process of building an application that uses Spring Data JPA to store and retrieve data in a relational database.\r\n\r\n## What you’ll build\r\nYou’ll build an application that stores `Customer` [POJOs](http://spring.io/understanding/POJO) in a memory-based database.\r\n\r\n### What you’ll need\r\n* About 15 minutes\r\n* A favorite text editor or IDE\r\n* [JDK 1.8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or later\r\n* [Gradle 4+](http://www.gradle.org/downloads) or [Maven 3.2+](https://maven.apache.org/download.cgi)\r\n* You can also import the code straight into your IDE:\r\n  - [Spring Tool Suite (STS)](http://spring.io/guides/gs/sts)\r\n  - [IntelliJ IDEA](http://spring.io/guides/gs/intellij-idea/)\r\n\r\n## How to complete this guide\r\nLike most Spring [Getting Started guides](http://spring.io/guides), you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.\r\n\r\nTo **start from scratch**, move on to [Build with Gradle](#build-with-gradle).\r\n\r\nTo **skip the basics**, do the following:\r\n\r\n* [Download](https://github.com/spring-guides/gs-accessing-data-jpa/archive/master.zip) and unzip the source repository for this guide, or clone it using [Git](http://spring.io/understanding/Git): `git clone https://github.com/spring-guides/gs-accessing-data-jpa.git`\r\n* cd into `gs-accessing-data-jpa/initial`\r\n* Jump ahead to [Define a simple entity](#define-a-simple-entity).\r\n\r\n**When you’re finished**, you can check your results against the code in `gs-accessing-data-jpa/complete`.\r\n\r\n## Build with Gradle\r\nFirst you set up a basic build script. You can use any build system you like when building apps with Spring, but the code you need to work with [Gradle](http://gradle.org/) and [Maven](https://maven.apache.org/) is included here. If you’re not familiar with either, refer to [Building Java Projects with Gradle](http://spring.io/guides/gs/gradle) or [Building Java Projects with Maven](http://spring.io/guides/gs/maven).\r\n\r\n### Create the directory structure\r\nIn a project directory of your choosing, create the following subdirectory structure; for example, with `mkdir -p src/main/java/hello` on *nix systems:\r\n\r\n```\r\n└── src\r\n    └── main\r\n        └── java\r\n            └── hello\r\n```\r\n\r\n### Create a Gradle build file\r\nBelow is the [initial Gradle build file](https://github.com/spring-guides/gs-accessing-data-jpa/blob/master/initial/build.gradle).\r\n\r\n`build.gradle`\r\n\r\n```gradle\r\nbuildscript {\r\n    repositories {\r\n        mavenCentral()\r\n    }\r\n    dependencies {\r\n        classpath(\"org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE\")\r\n    }\r\n}\r\n\r\napply plugin: 'java'\r\napply plugin: 'eclipse'\r\napply plugin: 'idea'\r\napply plugin: 'org.springframework.boot'\r\napply plugin: 'io.spring.dependency-management'\r\n\r\nbootJar {\r\n    baseName = 'gs-accessing-data-jpa'\r\n    version =  '0.1.0'\r\n}\r\n\r\nrepositories {\r\n    mavenCentral()\r\n    maven { url \"https://repository.jboss.org/nexus/content/repositories/releases\" }\r\n}\r\n\r\nsourceCompatibility = 1.8\r\ntargetCompatibility = 1.8\r\n\r\ndependencies {\r\n    compile(\"org.springframework.boot:spring-boot-starter-data-jpa\")\r\n    compile(\"com.h2database:h2\")\r\n    testCompile(\"junit:junit\")\r\n}\r\n```\r\n\r\nThe [Spring Boot gradle plugin](https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html) provides many convenient features:\r\n\r\n* It collects all the jars on the classpath and builds a single, runnable \"über-jar\", which makes it more convenient to execute and transport your service.\r\n* It searches for the `public static void main()` method to flag as a runnable class.\r\n* It provides a built-in dependency resolver that sets the version number to match [Spring Boot dependencies](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-dependencies/pom.xml). You can override any version you wish, but it will default to Boot’s chosen set of versions.\r\n\r\n## Build with Maven\r\nFirst you set up a basic build script. You can use any build system you like when building apps with Spring, but the code you need to work with [Maven](https://maven.apache.org/) is included here. If you’re not familiar with Maven, refer to [Building Java Projects with Maven](http://spring.io/guides/gs/maven).\r\n\r\n### Create the directory structure\r\nIn a project directory of your choosing, create the following subdirectory structure; for example, with `mkdir -p src/main/java/hello` on *nix systems:\r\n\r\n```\r\n└── src\r\n    └── main\r\n        └── java\r\n            └── hello\r\n```\r\n\r\n`pom.xml`\r\n\r\n```xml\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\r\n    xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\"\r\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n\r\n    <groupId>org.springframework</groupId>\r\n    <artifactId>gs-accessing-data-jpa</artifactId>\r\n    <version>0.1.0</version>\r\n\r\n    <parent>\r\n        <groupId>org.springframework.boot</groupId>\r\n        <artifactId>spring-boot-starter-parent</artifactId>\r\n        <version>2.0.5.RELEASE</version>\r\n    </parent>\r\n\r\n    <properties>\r\n        <java.version>1.8</java.version>\r\n    </properties>\r\n\r\n    <dependencies>\r\n        <dependency>\r\n            <groupId>org.springframework.boot</groupId>\r\n            <artifactId>spring-boot-starter-data-jpa</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.h2database</groupId>\r\n            <artifactId>h2</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.springframework.boot</groupId>\r\n            <artifactId>spring-boot-starter-test</artifactId>\r\n            <scope>test</scope>\r\n        </dependency>\r\n    </dependencies>\r\n\r\n    <build>\r\n        <plugins>\r\n            <plugin>\r\n                <groupId>org.springframework.boot</groupId>\r\n                <artifactId>spring-boot-maven-plugin</artifactId>\r\n            </plugin>\r\n        </plugins>\r\n    </build>\r\n\r\n    <repositories>\r\n        <repository>\r\n            <id>spring-releases</id>\r\n            <name>Spring Releases</name>\r\n            <url>https://repo.spring.io/libs-release</url>\r\n        </repository>\r\n        <repository>\r\n            <id>org.jboss.repository.releases</id>\r\n            <name>JBoss Maven Release Repository</name>\r\n            <url>https://repository.jboss.org/nexus/content/repositories/releases</url>\r\n        </repository>\r\n    </repositories>\r\n\r\n    <pluginRepositories>\r\n        <pluginRepository>\r\n            <id>spring-releases</id>\r\n            <name>Spring Releases</name>\r\n            <url>https://repo.spring.io/libs-release</url>\r\n        </pluginRepository>\r\n    </pluginRepositories>\r\n\r\n</project>\r\n```\r\n\r\nThe [Spring Boot Maven plugin](https://docs.spring.io/spring-boot/docs/current/maven-plugin) provides many convenient features:\r\n\r\n* It collects all the jars on the classpath and builds a single, runnable \"über-jar\", which makes it more convenient to execute and transport your service.\r\n* It searches for the `public static void main()` method to flag as a runnable class.\r\n* It provides a built-in dependency resolver that sets the version number to match [Spring Boot dependencies](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-dependencies/pom.xml). You can override any version you wish, but it will default to Boot’s chosen set of versions.\r\n\r\n## Build with your IDE\r\n* Read how to import this guide straight into [Spring Tool Suite](http://spring.io/guides/gs/sts/).\r\n* Read how to work with this guide in [IntelliJ IDEA](http://spring.io/guides/gs/intellij-idea).\r\n\r\n## Define a simple entity\r\nIn this example, you store Customer objects, annotated as a JPA entity.\r\n\r\n`src/main/java/hello/Customer.java`\r\n\r\n```java\r\npackage hello;\r\n\r\nimport javax.persistence.Entity;\r\nimport javax.persistence.GeneratedValue;\r\nimport javax.persistence.GenerationType;\r\nimport javax.persistence.Id;\r\n\r\n@Entity\r\npublic class Customer {\r\n\r\n    @Id\r\n    @GeneratedValue(strategy=GenerationType.AUTO)\r\n    private Long id;\r\n    private String firstName;\r\n    private String lastName;\r\n\r\n    protected Customer() {}\r\n\r\n    public Customer(String firstName, String lastName) {\r\n        this.firstName = firstName;\r\n        this.lastName = lastName;\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        return String.format(\r\n                \"Customer[id=%d, firstName='%s', lastName='%s']\",\r\n                id, firstName, lastName);\r\n    }\r\n\r\n}\r\n```\r\n\r\nHere you have a `Customer` class with three attributes, the `id`, the `firstName`, and the lastName. You also have two constructors. The default constructor only exists for the sake of JPA. You won’t use it directly, so it is designated as `protected`. The other constructor is the one you’ll use to create instances of `Customer` to be saved to the database.\r\n\r\n> In this guide, the typical getters and setters have been left out for brevity.\r\n\r\nThe `Customer` class is annotated with `@Entity`, indicating that it is a JPA entity. For lack of a `@Table` annotation, it is assumed that this entity will be mapped to a table named `Customer`.\r\n\r\nThe `Customer`’s `id` property is annotated with `@Id` so that JPA will recognize it as the object’s ID. The `id` property is also annotated with `@GeneratedValue` to indicate that the ID should be generated automatically.\r\n\r\nThe other two properties, `firstName` and `lastName` are left unannotated. It is assumed that they’ll be mapped to columns that share the same name as the properties themselves.\r\n\r\nThe convenient `toString()` method will print out the customer’s properties.\r\n\r\n## Create simple queries\r\nSpring Data JPA focuses on using JPA to store data in a relational database. Its most compelling feature is the ability to create repository implementations automatically, at runtime, from a repository interface.\r\n\r\nTo see how this works, create a repository interface that works with `Customer` entities:\r\n\r\n`src/main/java/hello/CustomerRepository.java`\r\n\r\n```java\r\npackage hello;\r\n\r\nimport java.util.List;\r\n\r\nimport org.springframework.data.repository.CrudRepository;\r\n\r\npublic interface CustomerRepository extends CrudRepository<Customer, Long> {\r\n\r\n    List<Customer> findByLastName(String lastName);\r\n}\r\n```\r\n\r\n`CustomerRepository` extends the `CrudRepository` interface. The type of entity and ID that it works with,`Customer` and `Long`, are specified in the generic parameters on `CrudRepository`. By extending `CrudRepository`, `CustomerRepository` inherits several methods for working with `Customer` persistence, including methods for saving, deleting, and finding `Customer` entities.\r\n\r\nSpring Data JPA also allows you to define other query methods by simply declaring their method signature. In the case of `CustomerRepository`, this is shown with a `findByLastName()` method.\r\n\r\nIn a typical Java application, you’d expect to write a class that implements `CustomerRepository`. But that’s what makes Spring Data JPA so powerful: You don’t have to write an implementation of the repository interface. Spring Data JPA creates an implementation on the fly when you run the application.\r\n\r\nLet’s wire this up and see what it looks like!\r\n\r\n## Create an Application class\r\nHere you create an Application class with all the components.\r\n\r\n`src/main/java/hello/Application.java`\r\n\r\n```java\r\npackage hello;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport org.springframework.boot.CommandLineRunner;\r\nimport org.springframework.boot.SpringApplication;\r\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\r\nimport org.springframework.context.annotation.Bean;\r\n\r\n@SpringBootApplication\r\npublic class Application {\r\n\r\n\tprivate static final Logger log = LoggerFactory.getLogger(Application.class);\r\n\r\n\tpublic static void main(String[] args) {\r\n\t\tSpringApplication.run(Application.class);\r\n\t}\r\n\r\n\t@Bean\r\n\tpublic CommandLineRunner demo(CustomerRepository repository) {\r\n\t\treturn (args) -> {\r\n\t\t\t// save a couple of customers\r\n\t\t\trepository.save(new Customer(\"Jack\", \"Bauer\"));\r\n\t\t\trepository.save(new Customer(\"Chloe\", \"O'Brian\"));\r\n\t\t\trepository.save(new Customer(\"Kim\", \"Bauer\"));\r\n\t\t\trepository.save(new Customer(\"David\", \"Palmer\"));\r\n\t\t\trepository.save(new Customer(\"Michelle\", \"Dessler\"));\r\n\r\n\t\t\t// fetch all customers\r\n\t\t\tlog.info(\"Customers found with findAll():\");\r\n\t\t\tlog.info(\"-------------------------------\");\r\n\t\t\tfor (Customer customer : repository.findAll()) {\r\n\t\t\t\tlog.info(customer.toString());\r\n\t\t\t}\r\n\t\t\tlog.info(\"\");\r\n\r\n\t\t\t// fetch an individual customer by ID\r\n\t\t\trepository.findById(1L)\r\n\t\t\t\t.ifPresent(customer -> {\r\n\t\t\t\t\tlog.info(\"Customer found with findById(1L):\");\r\n\t\t\t\t\tlog.info(\"--------------------------------\");\r\n\t\t\t\t\tlog.info(customer.toString());\r\n\t\t\t\t\tlog.info(\"\");\r\n\t\t\t\t});\r\n\r\n\t\t\t// fetch customers by last name\r\n\t\t\tlog.info(\"Customer found with findByLastName('Bauer'):\");\r\n\t\t\tlog.info(\"--------------------------------------------\");\r\n\t\t\trepository.findByLastName(\"Bauer\").forEach(bauer -> {\r\n\t\t\t\tlog.info(bauer.toString());\r\n\t\t\t});\r\n\t\t\t// for (Customer bauer : repository.findByLastName(\"Bauer\")) {\r\n\t\t\t// \tlog.info(bauer.toString());\r\n\t\t\t// }\r\n\t\t\tlog.info(\"\");\r\n\t\t};\r\n\t}\r\n\r\n}\r\n```\r\n\r\n`@SpringBootApplication` is a convenience annotation that adds all of the following:\r\n\r\n* `@Configuration` tags the class as a source of bean definitions for the application context.\r\n* `@EnableAutoConfiguration` tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.\r\n* Normally you would add `@EnableWebMvc` for a Spring MVC app, but Spring Boot adds it automatically when it sees **spring-webmvc** on the classpath. This flags the application as a web application and activates key behaviors such as setting up a `DispatcherServlet`.\r\n* `@ComponentScan` tells Spring to look for other components, configurations, and services in the `hello` package, allowing it to find the controllers.\r\n\r\nThe `main()` method uses Spring Boot’s `SpringApplication.run()` method to launch an application. Did you notice that there wasn’t a single line of XML? No **web.xml** file either. This web application is 100% pure Java and you didn’t have to deal with configuring any plumbing or infrastructure.\r\n\r\n`Application` includes a `main()` method that puts the `CustomerRepository` through a few tests. First, it fetches the `CustomerRepository` from the Spring application context. Then it saves a handful of `Customer` objects, demonstrating the `save()` method and setting up some data to work with. Next, it calls `findAll()` to fetch all `Customer` objects from the database. Then it calls `findOne()` to fetch a single `Customer` by its ID. Finally, it calls `findByLastName()` to find all customers whose last name is \"Bauer\".\r\n\r\n> By default, Spring Boot will enable JPA repository support and look in the package (and its subpackages) where `@SpringBootApplication` is located. If your configuration has JPA repository interface definitions located in a package not visible, you can point out alternate packages using `@EnableJpaRepositories` and its type-safe `basePackageClasses=MyRepository.class` parameter.\r\n\r\n## Build an executable JAR\r\nYou can run the application from the command line with Gradle or Maven. Or you can build a single executable JAR file that contains all the necessary dependencies, classes, and resources, and run that. This makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.\r\n\r\nIf you are using Gradle, you can run the application using `./gradlew bootRun`. Or you can build the JAR file using `./gradlew build`. Then you can run the JAR file:\r\n\r\n```\r\njava -jar build/libs/gs-accessing-data-jpa-0.1.0.jar\r\n```\r\n\r\nIf you are using Maven, you can run the application using `./mvnw spring-boot:run`. Or you can build the JAR file with `./mvnw clean package`. Then you can run the JAR file:\r\n\r\n```\r\njava -jar target/gs-accessing-data-jpa-0.1.0.jar\r\n```\r\n\r\n> The procedure above will create a runnable JAR. You can also opt to [build a classic WAR file](http://spring.io/guides/gs/convert-jar-to-war/) instead.\r\n\r\nYou should see something like this:\r\n\r\n```\r\n== Customers found with findAll():\r\nCustomer[id=1, firstName='Jack', lastName='Bauer']\r\nCustomer[id=2, firstName='Chloe', lastName='O'Brian']\r\nCustomer[id=3, firstName='Kim', lastName='Bauer']\r\nCustomer[id=4, firstName='David', lastName='Palmer']\r\nCustomer[id=5, firstName='Michelle', lastName='Dessler']\r\n\r\n== Customer found with findOne(1L):\r\nCustomer[id=1, firstName='Jack', lastName='Bauer']\r\n\r\n== Customer found with findByLastName('Bauer'):\r\nCustomer[id=1, firstName='Jack', lastName='Bauer']\r\nCustomer[id=3, firstName='Kim', lastName='Bauer']\r\n```\r\n\r\n## Summary\r\nCongratulations! You’ve written a simple application that uses Spring Data JPA to save objects to a database and to fetch them — all without writing a concrete repository implementation.\r\n\r\n> If you’re interested in exposing JPA repositories with a hypermedia-based RESTful front end with little effort, you might want to read [Accessing JPA Data with REST](http://spring.io/guides/gs/accessing-data-rest).\r\n\r\n## See Also\r\nThe following guides may also be helpful:\r\n\r\n* [Accessing Data with Gemfire](https://spring.io/guides/gs/accessing-data-gemfire/)\r\n* [Accessing Data with MongoDB](https://spring.io/guides/gs/accessing-data-mongodb/)\r\n* [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/)\r\n* [Accessing Data with Neo4j](https://spring.io/guides/gs/accessing-data-neo4j/)"}}
{"actor":{"display_login":"Hanope"}}