Spring 引导 JPA 插入和更新
Spring Boot JPA Insert and Update
好的,我环顾四周以找到这个答案大约一个小时,但我看不到它已发布。所以我在 Udemy 上从 in28minutes 买了 Spring Framework Master Class。我们已经开始实施 JPA。但是Spring Boot版本不同(他用的是2.0.3,我用的是2.4.0)。现在我知道这就是问题所在。所以任务是简单地连接到 h2 数据库,并与数据交互。这是我正在使用的当前代码设置:
JpaDemoApplication.java
package com.in28minutes.database.databasedemo;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.in28minutes.database.databasedemo.entity.Person;
import com.in28minutes.database.databasedemo.jpa.PersonJpaRepository;
@SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
PersonJpaRepository repository;
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
logger.info("User id 10001 -> {}", repository.findById(10001));
logger.info("Inserting -> {}",
repository.insert(new Person("Tara", "Berlin", new Date())));
/*
logger.info("Update 10003 -> {}",
repository.update(new Person(10003, "Pieter", "Utrecht", new Date())));
//repository.deleteById(10002);
logger.info("All users -> {}", repository.findAll());
*/
}
}
Person.java
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
@Entity
@NamedQuery(name="find_all_persons", query="select p from Person p")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String location;
private Date birthDate;
public Person() {}
public Person(int id, String name, String location, Date birthDate) {
super();
this.id = id;
this.name = name;
this.location = location;
this.birthDate = birthDate;
}
public Person(String name, String location, Date birthDate) {
super();
this.name = name;
this.location = location;
this.birthDate = birthDate;
}
public int getId() { return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getLocation() {return location;}
public void setLocation(String location) {this.location = location;}
public Date getBirthDate() {return birthDate;}
public void setBirthDate(Date birthDate) {this.birthDate = birthDate;}
@Override
public String toString() {
return String.format("\nPerson [id=%s, name=%s, location=%s, birthDate=%s]", id, name, location, birthDate);
}
}
PersonJpaRepository.java
package com.in28minutes.database.databasedemo.jpa;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
import org.springframework.stereotype.Repository;
import com.in28minutes.database.databasedemo.entity.Person;
@Repository
@Transactional
public class PersonJpaRepository {
// connect to the database
@PersistenceContext
EntityManager entityManager;
public List<Person> findAll() {
TypedQuery<Person> namedQuery = entityManager.createNamedQuery("find_all_persons", Person.class);
return namedQuery.getResultList();
}
public Person findById(int id) {
return entityManager.find(Person.class, id);// JPA
}
public Person update(Person person) {
return entityManager.merge(person);
}
public Person insert(Person person) {
return entityManager.merge(person);
}
public void deleteById(int id) {
Person person = findById(id);
entityManager.remove(person);
}
}
application.properties
spring.h2.console.enabled=true
spring.jpa.show-sql=true
#logging.level.root=debug
#spring.jpa.hibernate.use-new-id-generator-mappings=false
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:h2:mem:testdb
spring.data.jpa.repositories.bootstrap-mode=default
data.sql
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE)
VALUES(10001, 'Ranga', 'Hyderabad', sysdate());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE)
VALUES(10002, 'James', 'New York', sysdate());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE)
VALUES(10003, 'Pieter', 'Amsterdam', sysdate());
schema.sql
create table person
(
id integer not null,
name varchar(255) not null,
location varchar(255),
birth_date timestamp,
primary key(id)
);
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.in28minutes.database</groupId>
<artifactId>database-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>database-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>15</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</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>
我知道这很多,但我是 Spring 的新手,我必须在 1 月之前完成这个,因为我要开始一份新工作。具体错误是创建了 table,第一个 select by id 有效,但插入传递了一个空值:
Hibernate: insert into person (id, birth_date, location, name) values (null, ?, ?, ?)
2020-12-03 10:59:16.724 WARN 14464 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23502, SQLState: 23502
2020-12-03 10:59:16.724 ERROR 14464 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : NULL not allowed for column "ID"; SQL statement:
insert into person (id, birth_date, location, name) values (null, ?, ?, ?) [23502-200]
我尝试了 5 种不同的建议,但 none 都奏效了。我究竟做错了什么?指出一些可以解释如何做到这一点的东西,我一直在寻找更多最新的学习资源。
@GeneratedValue
注解用于自动生成主键值。生成类型有4种:AUTO、IDENTITY、SEQUENCE、TABLE.
AUTO:持久性提供程序将根据主键属性的类型确定值。 Numeric
值基于序列生成器生成,UUID
值使用 UUIDGenerator
.
IDENTITY:它依赖于数据库中标识列生成的值,这意味着它们是自动的-增加。请注意,IDENTITY 生成禁用批量更新。
您正在使用 IDENTITY 策略,但架构中没有 identity
列。更改 schema.sql
如下:
create table person
(
id integer generated by default as identity not null,
name varchar(255) not null,
location varchar(255),
birth_date timestamp,
primary key(id)
);
好的,我环顾四周以找到这个答案大约一个小时,但我看不到它已发布。所以我在 Udemy 上从 in28minutes 买了 Spring Framework Master Class。我们已经开始实施 JPA。但是Spring Boot版本不同(他用的是2.0.3,我用的是2.4.0)。现在我知道这就是问题所在。所以任务是简单地连接到 h2 数据库,并与数据交互。这是我正在使用的当前代码设置:
JpaDemoApplication.java
package com.in28minutes.database.databasedemo;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.in28minutes.database.databasedemo.entity.Person;
import com.in28minutes.database.databasedemo.jpa.PersonJpaRepository;
@SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
PersonJpaRepository repository;
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
logger.info("User id 10001 -> {}", repository.findById(10001));
logger.info("Inserting -> {}",
repository.insert(new Person("Tara", "Berlin", new Date())));
/*
logger.info("Update 10003 -> {}",
repository.update(new Person(10003, "Pieter", "Utrecht", new Date())));
//repository.deleteById(10002);
logger.info("All users -> {}", repository.findAll());
*/
}
}
Person.java
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
@Entity
@NamedQuery(name="find_all_persons", query="select p from Person p")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String location;
private Date birthDate;
public Person() {}
public Person(int id, String name, String location, Date birthDate) {
super();
this.id = id;
this.name = name;
this.location = location;
this.birthDate = birthDate;
}
public Person(String name, String location, Date birthDate) {
super();
this.name = name;
this.location = location;
this.birthDate = birthDate;
}
public int getId() { return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getLocation() {return location;}
public void setLocation(String location) {this.location = location;}
public Date getBirthDate() {return birthDate;}
public void setBirthDate(Date birthDate) {this.birthDate = birthDate;}
@Override
public String toString() {
return String.format("\nPerson [id=%s, name=%s, location=%s, birthDate=%s]", id, name, location, birthDate);
}
}
PersonJpaRepository.java
package com.in28minutes.database.databasedemo.jpa;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
import org.springframework.stereotype.Repository;
import com.in28minutes.database.databasedemo.entity.Person;
@Repository
@Transactional
public class PersonJpaRepository {
// connect to the database
@PersistenceContext
EntityManager entityManager;
public List<Person> findAll() {
TypedQuery<Person> namedQuery = entityManager.createNamedQuery("find_all_persons", Person.class);
return namedQuery.getResultList();
}
public Person findById(int id) {
return entityManager.find(Person.class, id);// JPA
}
public Person update(Person person) {
return entityManager.merge(person);
}
public Person insert(Person person) {
return entityManager.merge(person);
}
public void deleteById(int id) {
Person person = findById(id);
entityManager.remove(person);
}
}
application.properties
spring.h2.console.enabled=true
spring.jpa.show-sql=true
#logging.level.root=debug
#spring.jpa.hibernate.use-new-id-generator-mappings=false
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:h2:mem:testdb
spring.data.jpa.repositories.bootstrap-mode=default
data.sql
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE)
VALUES(10001, 'Ranga', 'Hyderabad', sysdate());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE)
VALUES(10002, 'James', 'New York', sysdate());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE)
VALUES(10003, 'Pieter', 'Amsterdam', sysdate());
schema.sql
create table person
(
id integer not null,
name varchar(255) not null,
location varchar(255),
birth_date timestamp,
primary key(id)
);
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.in28minutes.database</groupId>
<artifactId>database-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>database-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>15</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</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>
我知道这很多,但我是 Spring 的新手,我必须在 1 月之前完成这个,因为我要开始一份新工作。具体错误是创建了 table,第一个 select by id 有效,但插入传递了一个空值:
Hibernate: insert into person (id, birth_date, location, name) values (null, ?, ?, ?)
2020-12-03 10:59:16.724 WARN 14464 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23502, SQLState: 23502
2020-12-03 10:59:16.724 ERROR 14464 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : NULL not allowed for column "ID"; SQL statement:
insert into person (id, birth_date, location, name) values (null, ?, ?, ?) [23502-200]
我尝试了 5 种不同的建议,但 none 都奏效了。我究竟做错了什么?指出一些可以解释如何做到这一点的东西,我一直在寻找更多最新的学习资源。
@GeneratedValue
注解用于自动生成主键值。生成类型有4种:AUTO、IDENTITY、SEQUENCE、TABLE.AUTO:持久性提供程序将根据主键属性的类型确定值。
Numeric
值基于序列生成器生成,UUID
值使用UUIDGenerator
.IDENTITY:它依赖于数据库中标识列生成的值,这意味着它们是自动的-增加。请注意,IDENTITY 生成禁用批量更新。
您正在使用 IDENTITY 策略,但架构中没有 identity
列。更改 schema.sql
如下:
create table person
(
id integer generated by default as identity not null,
name varchar(255) not null,
location varchar(255),
birth_date timestamp,
primary key(id)
);