Как мне создать H2, используя SpringBoot?
Я начинаю играть с Spring Boot, и как часть этого я хочу создать БД в памяти для работы и загрузки приложения.
Учитывая приведенный ниже конфиг / код, я не получаю ошибок в журнале запуска и могу нормально обращаться к приложению, поэтому оно запускается (я получаю ошибки шаблона о несуществующих объектах), но я не получаю никаких данных из DAO при вызове findAll() (или если я пытаюсь вызвать findById(int)).
Таким образом, хотя кажется, что все в порядке (в журнале нет ошибок, журнал показывает, что находит sql для создания схемы и пытается выполнить операторы data.sql), когда я пытаюсь получить доступ к данным через DAO, я не получаю никаких исключений, но данные не возвращаются,
Любые идеи или замечания по коду, которые могут быть проблемой?
Я добавил материал Spring Data / H2 в мой pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
Весна ДАО:
public interface PersonDao extends CrudRepository<Person, Integer> {
}
БД реквизит в application.properties:
server.contextPath=/
server.port=8080
spring.mvc.view.suffix=.ftl
datasource.mine.jdbcUrl=jdbc:h2:tcp://localhost/mem:clubmanagement
datasource.mine.user=sa
datasource.mine.password=
datasource.mine.poolSize=30
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=DEBUG
spring.jpa.hibernate.ddl-auto=create
Мой сервис:
@Service
public class MemberServiceImpl implements MemberService {
@Autowired
PersonDao dao;
@Override
public Optional<ClubMember> getClubMember(int id) {
Person dbPerson = dao.findOne(id);
if(dbPerson == null) {
return Optional.empty();
}
return Optional.of(fromEntity(dbPerson));
}
@Override
public List<ClubMember> allMembers() {
Iterable<Person> people = dao.findAll();
List<ClubMember> members = new ArrayList<>();
people.forEach(person -> {
members.add(fromEntity(person));
});
return members;
}
private ClubMember fromEntity(Person p) {
ClubMember member = new ClubMember();
member.setCurrentGrade(p.getCurrentGrade());
member.setFirstName(p.getFirstName());
member.setLastName(p.getLastName());
member.setAssociationMemberId(p.getAssociationMemberId());
member.setLastGradingDate(p.getLastGradingDate());
return member;
}
}
Schema.sql в ресурсах /:
create table CLUB
(id int not null, name varchar(60), association_member_id int);
create table PERSON
(
id int not null, grade_id int, first_name varchar(35), last_name varchar(35),
association_membership varchar(12), last_grading_date date
);
create table GRADE
(id int not null, name varchar(20));
В data.sql (снова в каталоге ресурсов):
insert into club (id, name, association_member_id) values (1, 'some club', '123');
insert into person (id, grade_id, first_name, last_name, association_membership, last_grading_date)
values (1, 1, 'name', 'lastname', 'a1234', '2016-03-23');
Класс сущности, который я пытаюсь получить (пытаясь использовать Lombock, также новый для меня, для генерации методов получения / установки):
@Entity
@Table(name = "person")
public @Data class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private int id;
@JoinColumn(name = "grade_id")
private GRADE currentGrade;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "association_membership")
private String associationMemberId;
@Column(name = "last_grading_date")
@Temporal(value = TemporalType.DATE)
private Date lastGradingDate;
}
3 ответа
Потратив некоторое время на проработку некоторых идей с @Safwan Hijazi в чате, пришли к выводу, что происходит то, что schema.sql и data.sql запускаются, но затем схема воссоздается в зависимости от значения (или отсутствия) свойства spring.jpa.hibernate.ddl-auto.
Если он не указан, то между ними и пружиной / спящим режимом воссоздается пустая схема (по умолчанию создается команда "создать-сбросить" в БД памяти).
Если установить 'none', этого не произойдет, и БД, созданная сценариями схемы и данных, останется, и приложение будет работать правильно.
Смотрите также: CrudRepository не читает данные из schema.sql
Вы хотите добавить базу данных H2, но вы добавили HSQLDB, пожалуйста, замените
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
с
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
РЕДАКТИРОВАТЬ
Я заметил, что у вас есть несколько проблем в вашем коде:
- имя файла схемы по умолчанию - schema.sql, а не Schema.sql
- имена таблиц в schema.sql отличаются от имен в data.sql (ЛИЦО против человека)
- ты использовал это
spring.jpa.hibernate.ddl-auto=create
в application.properties (опция по умолчанию), в этом случае будет автоматически создана только схема баз данных JPA (без создания данных), поэтому data.sql не будет выполнен, для устранения этой проблемы вы можете использоватьvalidate
или жеupdate
вариант
Я напишу один простой пример, как использовать базу данных H2 с весенней загрузкой и JPA
Это структура проекта:
Класс сущность
package com.shijazi;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="GRADE")
public class Grade {
@Id
@GeneratedValue
private int id;
private String name;
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 Grade(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Grade() {
}
}
GradeRepository.java
package com.shijazi;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface GradeRepository extends JpaRepository<Grade, Integer> {
}
Application.java
@SpringBootApplication
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Autowired
private GradeRepository gradeRepo;
@RequestMapping(value="api/test")
public List<Grade> getall()
{
return gradeRepo.findAll();
}
}
application.properties
spring.jpa.hibernate.ddl-auto=validate
schema.sql
create table GRADE (id int not null, name varchar(20));
data.sql
insert into GRADE (id, name) values (2, 'name');
Зависимости в pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</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>
Теперь просто запустите приложение и назовите этот URL: http://localhost:8080/api/test
попытаться изменить spring.jpa.hibernate.ddl-auto
и посмотреть результаты
если вы активируете ddl-auto и имеете schema.sql, ОБА из них выполняются. Но обычно schema.sql выполняется первым. Таким образом, ddl-auto выбрасывает все, что было создано schema.sql и data.sql
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Просто дает вам пружинное упрямое включение в spring-boot-starter-data-jpa
файл maven, для спецификации материалов всех зависимостей. Использовать любую из зависимостей, определенных в управлении зависимостями spring-boot-starter-data-jpa
pom вам нужно будет явно объявить зависимость в разделе зависимостей вашего файла pom.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
Чтобы запустить базу данных h2 вместе с вашим приложением, вы можете указать свойства в файле application.properties по адресу src/main/resources/application.properties
использовать:
spring.h2.console.enabled=true
spring.h2.console.path=/h2DB
поэтому, когда вы запустите свое приложение с помощью Spring Spring Starter, вы сможете получить доступ к приложению по адресу http://localhost:8080/h2DB
войдите в базу данных, и вы можете проверить, есть ли в базе данных вставки или нет?
Не находите данные там, тогда вы знаете, где внести изменения, чтобы сохранить данные там.