#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 работает нормально, проблема кроется где-то в другом месте, я верю в соединение, поскольку подозреваю, что оно создает новое (?), А не использует то, что у него есть