Как мне создать 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>

РЕДАКТИРОВАТЬ

Я заметил, что у вас есть несколько проблем в вашем коде:

  1. имя файла схемы по умолчанию - schema.sql, а не Schema.sql
  2. имена таблиц в schema.sql отличаются от имен в data.sql (ЛИЦО против человека)
  3. ты использовал это 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 войдите в базу данных, и вы можете проверить, есть ли в базе данных вставки или нет?

Не находите данные там, тогда вы знаете, где внести изменения, чтобы сохранить данные там.

Другие вопросы по тегам