Spring Boot / Hibernate / Mysql无法创建EntityManagerFactory

时间:2016-10-23 10:30:21

标签: mysql spring hibernate spring-boot

我是Spring Boot的新手,我需要你的帮助。我正在尝试配置我的MySQL数据库,JPA(Hibernate),但我有以下例外:

  

创建名为'entityManagerFactory'的bean在类路径资源中定义时出错.....

     

引起:org.hibernate.AnnotationException:无法在表联系人上创建唯一键约束(user_id,email):找不到数据库列'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

Hibernate 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);
    }
}

bean的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;
    }
}

我尝试在spring-app.xml的帮助下配置EntityManagerFactory,但它仍无效。

 @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 个答案:

答案 0 :(得分:1)

联系人实体没有引用User对象的字段用户。所以hibernate映射中没有user_id列。 Hibernate不会检查数据库中的列。