Spring MVC с таблицей метаний H2 не найден

#java #spring #hibernate #jpa #h2

#java #весна #спящий режим #jpa #h2

Вопрос:

Я знаю, что такого рода вопросы возникали много раз, но я все еще чего-то не хватает. Я создаю какое-то простое приложение для веб-магазина с классическим Spring MVC (не загружается !), JPA с гибернацией и неудачным H2 🙂

Это мой application.properties :

 ################### DataSource Configuration ##########################
spring.datasource.url=jdbc:h2:mem:webshop;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.platform=h2
spring.datasource.username=webshopdba
spring.datasource.password=123
spring.datasource.initialize=true
################### JPA ###################
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
################### H2 ###################
spring.h2.console.path=/h2
spring.h2.console.enabled=true
################### Hibernate ###################
logging.level.org.hibernate.SQL=INFO
hibernate.show-sql=true
  

Вот пример класса модели:

 package com.webshop.model;

import lombok.Data;

import javax.persistence.*;
import java.util.Date;

@Entity
@Data
@Table(name = "PROGRAM")
public class Program {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;

    @Column(name = "PROGRAM_NAME")
    private String programName;

    @Column(name = "DESCRIPTION")
    private String description;
}
  

И вот конфигурация сохранения:

 
@Configuration
@EnableSpringDataWebSupport
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
@ComponentScan(basePackages = "com.webshop.repositories")
@EnableJpaRepositories(basePackages = "com.webshop.repositories")
public class PersistenceConfig {

    private final Environment env;

    @Autowired
    public PersistenceConfig(Environment env) {
        this.env = env;
    }

    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .setName("webshop")
                .build();
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        Properties jpaProperties = new Properties();
        jpaProperties.put("hibernate.show-sql", env.getProperty("hibernate.show-sql"));
        jpaProperties.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect"));
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(dataSource());
        factory.setPackagesToScan("com.webshop");
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setJpaProperties(jpaProperties);
        factory.afterPropertiesSet();
        return factory.getObject();
    }

    @Bean
    public DataSourceInitializer dataSourceInitializer() {
        ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
        resourceDatabasePopulator.addScript(new ClassPathResource("/schema-h2.sql"));

        DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
        dataSourceInitializer.setDataSource(dataSource());
        dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
        return dataSourceInitializer;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }
}

  

И вот schema-h2.sql :

 CREATE SCHEMA IF NOT EXISTS webshop;

SET SCHEMA webshop;

CREATE USER IF NOT EXISTS WEBSHOPDBA PASSWORD '123' ADMIN;

CREATE TABLE IF NOT EXISTS PROGRAM
(
    ID                  BIGINT PRIMARY KEY AUTO_INCREMENT,
    PROGRAM_NAME        VARCHAR(255),
    DESCRIPTION         VARCHAR(255)
);

INSERT INTO PROGRAM
(PROGRAM_NAME, DESCRIPTION)
VALUES ('Example software', 'Example')
  

Прямо сейчас приложение загружается должным образом, считывает schema-h2.sql, загружает его, и оно готово к работе, но если я делаю что-либо, связанное с сохранением, оно выдает

 SqlExceptionHelper:142 - Table "PROGRAM" not found; SQL statement:
insert into PROGRAM (PROGRAM_NAME, DESCRIPTION) values (null, ?, ?) [42102-196]
  

Хотя я могу использовать /h2-console path и попасть в H2, где присутствуют моя схема, таблица и один пример вставки (с пользователем, определенным в SQL). Я также вижу в журналах tomcat, что мои запросы были выполнены успешно. В чем может быть проблема здесь? Я чувствую, что при попытке выполнить какое-либо действие сохранения мой код создает новый экземпляр базы данных, а предыдущий теряется, однако DB_CLOSE_DELAY=-1 следует предотвратить это в соответствии с документами H2.

Что я пробовал до сих пор:

  • Настройка режима гибернации ddl-auto или hibernate.hbm2ddl.auto для создания / create-drop / update / none — нет разницы, spring.jpa.hibernate.ddl-auto=create
  • Разделение моего SQL-файла на схему / данные, импорт, просто схема, никакой разницы,
  • Явное объявление spring.datasource.initialization-mode=embedded без эффекта,
  • Добавление схемы инициализации в строку подключения,
  • Объявление источника данных с помощью DriverManagerDataSource

У меня постепенно заканчиваются идеи, может кто-нибудь посоветовать мне, что я могу здесь делать неправильно? Помогите мне, StackOverflow, вы моя единственная надежда!

Комментарии:

1. я думаю, что оператор create синтаксически неверен, попробуйте удалить «,» в «DESCRIPTION VARCHAR (255),»

2. Спасибо за ответ, это правда, хотя это была ошибка в моей копипасте 🙂 Этого нет в реальном коде, я обновил фрагмент

3. Вам не нужно указывать NOT NULL при настройке первичного ключа, поэтому вы можете создать таблицу, такую как; ID INT AUTO_INCREMENT PRIMARY KEY,

4. Это справедливое замечание, спасибо, я применю это изменение. Тем не менее, сам запрос управляет созданной таблицей должным образом, по крайней мере, это то, что я вижу в / h2-console, я определенно больше сосредоточусь на очистке кода и оптимизации, как только я попаду в рабочую базу данных.

5. Просто чтобы внести ясность, я выполнил проверку, вручную войдя в h2 с помощью консоли — (jdbc: h2: mem: webshop; DB_CLOSE_DELAY=-1) и мой запрос schema insert работает нормально, проблема кроется где-то в другом месте, я верю в соединение, поскольку подозреваю, что оно создает новое (?), А не использует то, что у него есть