0

I am new with Spring Boot and I need your help. I am trying to configure my MySQL DB, JPA (Hibernate) but I got the following exceptions:

Error creating bean with name 'entityManagerFactory' defined in class path resource .....

Caused by: org.hibernate.AnnotationException: Unable to create unique key constraint (user_id, email) on table contacts: database column 'user_id' not found.....

I can not find the answer in Internet. Please, help me someone. Thanks. My code:

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

My properties:

#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>

Application Configuration:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class SpringBootWebApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }
}

JPA Configuration for beans:

@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;
    }
}

I tried to configure EntityManagerFactory with the help of spring-app.xml but it still is not working.

 @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>
17
  • can we see your domain class (users, contacts)? Also, application.properties is more than enough to create a datasource. instead you have 3 data sources. Also show your pom.xml Commented Oct 23, 2016 at 10:55
  • I edited my question with entity and poom. Commented Oct 23, 2016 at 11:15
  • Should I delete datasources in hibernate.cnf.xml and JPAConfic.class? Commented Oct 23, 2016 at 11:16
  • Yes. delete them. Commented Oct 23, 2016 at 11:20
  • Still the same problem. Commented Oct 23, 2016 at 11:24

1 Answer 1

1

The contact entity does not have a field user that references a User object. So there is no user_id column in the hibernate mapping. Hibernate does not check the columns in the database.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.