#mysql #spring #hibernate #spring-boot
#mysql #spring #спящий режим #весенняя загрузка
Вопрос:
Я новичок в Spring Boot, и мне нужна ваша помощь. Я пытаюсь настроить свою базу данных MySQL, JPA (спящий режим), но я получил следующие исключения:
Ошибка при создании компонента с именем ‘EntityManagerFactory’, определенным в ресурсе пути к классу…..
Вызвано: org.hibernate.Исключение AnnotationException: Не удается создать ограничение уникального ключа (user_id, email) в таблице contacts: столбец базы данных ‘user_id’ не найден…..
Я не могу найти ответ в Интернете. Пожалуйста, помогите мне кто-нибудь. Спасибо. Мой код:
CREATE TABLE IF NOT EXISTS users
(
id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT,
login VARCHAR(45) NOT NULL,
password VARCHAR(45) NOT NULL,
full_name VARCHAR(100) NOT NULL
);
CREATE UNIQUE INDEX users_unique_login_idx ON users (login);
CREATE TABLE IF NOT EXISTS user_roles
(
user_id INTEGER NOT NULL,
role VARCHAR(45),
CONSTRAINT user_roles_idx UNIQUE (user_id, role),
FOREIGN KEY (user_id) REFERENCES users (id)
);
CREATE TABLE IF NOT EXISTS contacts (
id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT,
user_id INTEGER NOT NULL,
first_name VARCHAR(45) NOT NULL,
last_name VARCHAR(45) NOT NULL,
patronymic VARCHAR(45) NOT NULL,
mobile_phone_number VARCHAR(15),
home_phone_number VARCHAR(15),
address VARCHAR(45),
email VARCHAR(30),
FOREIGN KEY (user_id) REFERENCES users (id)
);
CREATE UNIQUE INDEX contacts_unique_idx ON contacts (user_id);
Мои свойства:
#You can use MySQL DB with next properties
spring.jpa.database=MYSQL
spring.datasource.url=jdbc:mysql://localhost:3306/lardi
spring.datasource.username=root
spring.datasource.password=2940063
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
use.SSL=false
Спящий режим config.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- properties -->
<property name="connection.url">jdbc:mysql://localhost:3306/lardi</property>
<property name="connection.username">root</property>
<property name="connection.password">2940063</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<!-- mapping files -->
<mapping class="com.model.BaseEntity"/>
<mapping class="com.model.NamedEntity"/>
<mapping class="com.model.Contact"/>
<mapping class="com.model.User"/>
<mapping class="com.model.Role"/>
</session-factory>
</hibernate-configuration>
Конфигурация приложения:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class SpringBootWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebApplication.class, args);
}
}
Конфигурация JPA для компонентов:
@Configuration
@EnableTransactionManagement
public class JPAConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.model");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/lardi");
dataSource.setUsername( "root" );
dataSource.setPassword( "2940063" );
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "validate");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
return properties;
}
}
Я попытался настроить EntityManagerFactory
с помощью spring-app.xml но это все еще не работает.
@Entity
@Table(name = "contacts", uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id"}, name = "unique_idx")})
public class Contact extends BaseEntity {
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "patronymic")
private String patronymic;
@Column(name = "mobile_phone_number")
private String mobilePhone;
@Column(name = "home_phone_number")
private String homePhone;
@Column(name = "address")
private String address;
@Column(name = "email")
private String email;
public Contact() {
}
public Contact(String firstName, String lastName, String patronymic, String mobilePhone, String homePhone, String address, String email ) {
this(null,firstName,lastName,patronymic,mobilePhone,homePhone,address,email);
}
public Contact( Integer id, String firstName, String lastName, String patronymic, String mobilePhone, String homePhone, String address, String email ) {
super(id);
this.firstName = firstName;
this.lastName = lastName;
this.patronymic = patronymic;
this.mobilePhone = mobilePhone;
this.homePhone = homePhone;
this.address = address;
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPatronymic() {
return patronymic;
}
public void setPatronymic(String patronymic) {
this.patronymic = patronymic;
}
public String getMobilePhone() {
return mobilePhone;
}
p
ublic void setMobilePhone(String mobilePhone) {
this.mobilePhone = mobilePhone;
}
public String getHomePhone() {
return homePhone;
}
public void setHomePhone(String homePhone) {
this.homePhone = homePhone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Contact{"
"firstName='" firstName '''
", lastName='" lastName '''
", patronymic='" patronymic '''
", mobilePhone='" mobilePhone '''
", homePhone='" homePhone '''
", address='" address '''
", email='" email '''
'}';
}
}
@Entity
@Table(name = "users", uniqueConstraints = {@UniqueConstraint(columnNames = "login", name = "users_unique_login_idx")})
public class User extends NamedEntity{
@Column(name = "password", nullable = false)
private String password;
@Column(name = "full_name", nullable = false)
private String fullName;
@Enumerated(EnumType.STRING)
@CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "role")
@ElementCollection(fetch = FetchType.LAZY)
protected Set<Role> roles;
public User() {
}
public User(User u) {
this(u.getId(), u.getLogin(), u.getPassword(), u. getFullName(), u.getRoles());
}
public User(Integer id, String login, String password, String fullName, Role role, Role... roles) {
this(id, login, password, fullName, EnumSet.of(role, roles));
}
public User(Integer id, String login, String password, String fullName, Set<Role> roles) {
super(id, login);
this.password = password;
this.fullName = fullName;
setRoles(roles);
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = CollectionUtils.isEmpty(roles) ? Collections.emptySet() : EnumSet.copyOf(roles);
}
@Override
public String toString() {
return "User{"
"password='" password '''
", fullName='" fullName '''
", roles=" roles
'}';
}
}
@MappedSuperclass
@Access(AccessType.FIELD)
public class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Integer id;
public BaseEntity() {
}
public BaseEntity(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public boolean isNew() {
return (this.id == null);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BaseEntity that = (BaseEntity) o;
if (id == null || that.id == null) {
return false;
}
return id.equals(that.id);
}
@Override
public int hashCode() {
return (id == null) ? 0 : id;
}
}
@MappedSuperclass
public class NamedEntity extends BaseEntity {
@NotEmpty
@Column(name = "login", nullable = false)
protected String login;
public NamedEntity() {
}
protected NamedEntity(Integer id, String login) {
super(id);
this.login = login;
}
public void setLogin(String login) {
this.login = login;
}
public String getLogin() {
return this.login;
}
@Override
public String toString() {
return login;
}
}
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>lardi</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Phone Book</name>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<start-class>com.SpringBootWebApplication</start-class>
<!-- JSON -->
<jackson-json.version>2.8.0</jackson-json.version>
<!-- WEB jars -->
<webjars-bootstrap.version>3.3.6</webjars-bootstrap.version>
<webjars-jquery.version>2.2.4</webjars-jquery.version>
<webjars-noty.version>2.3.8</webjars-noty.version>
<webjars-datatables.version>1.10.12</webjars-datatables.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<dependencies>
<!-- Spring Boot WEB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Boot TEST -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Boot JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-json.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
<version>${jackson-json.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-json.version}</version>
</dependency>
<!-- Webjars -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${webjars-bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>${webjars-jquery.version}</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>noty</artifactId>
<version>${webjars-noty.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>datatables</artifactId>
<version>${webjars-datatables.version}</version>
</dependency>
</dependencies>
</project>
Комментарии:
1. можем ли мы увидеть класс вашего домена (пользователи, контакты)? Кроме того, application.properties более чем достаточно для создания источника данных. вместо этого у вас есть 3 источника данных. Также покажите свой pom.xml
2. Я отредактировал свой вопрос с помощью entity и poom.
3. Должен ли я удалять источники данных в hibernate.cnf.xml и JPAConfic.class ?
4. Да. удалите их.
5. Все та же проблема.
Ответ №1:
У объекта contact нет поля user, которое ссылается на объект User. Таким образом, в сопоставлении hibernate нет столбца user_id. Hibernate не проверяет столбцы в базе данных.