4

Please, is there any way I can generate database tables from entity classes using hibernate in Intellij Idea? All I saw online is generate entity class from database schema. But I need the other way round for easy update to my database when I modify any entity class.

Here is my hibernate.cfg.xml file

<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/my_db?useSSL=false</property>


<property name="connection.username">username</property>
<property name="connection.password">password</property>


<property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>

<property name="show_sql">true</property>

<property name="current_session_context_class">thread</property>

<property name="hbm2ddl.auto">create</property>


<property name="connection.pool_size">1</property>
<property name="hibernate.dbcp.initialSize">5</property>
<property name="hibernate.dbcp.maxTotal">20</property>
<property name="hibernate.dbcp.maxIdle">10</property>
<property name="hibernate.dbcp.minIdle">5</property>
<property name="hibernate.dbcp.maxWaitMillis">-1</property>


<!--Declaring entity classes to be mapped to the database-->
<mapping class="com.softpager.estores.entities.Order" />
<mapping class="com.softpager.estores.entities.Customer" />
<mapping class="com.softpager.estores.entities.Users" />
<mapping class="com.softpager.estores.entities.Product" />   

Here is my persistence.xml file

 <persistence-unit name="EStores">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <properties>
        <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/my_db?useSSL=false"/>
        <property name="hibernate.connection.driver_class" value="com.mysql.cj.jdbc.Driver"/>
        <property name="hibernate.connection.username" value="username"/>
        <property name="hibernate.connection.password" value="password"/>
        <property name="hibernate.archive.autodetection" value="class"/>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.format_sql" value="true"/>
        <property name="hibernate.hbm2ddl.auto" value="create"/>

        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
        <property name="javax.persistence.schema-generation.create-source" value="metadata"/>
        <property name="javax.persistence.schema-generation.drop-source" value="metadata"/>
        <property name="javax.persistence.sql-load-script-source" value="META-INF/load.sql"/>
    </properties>

</persistence-unit>

Here is my Main.class

public class Main {
public static void main(String[] args) {
    EntityManagerFactory factory = createEntityManagerFactory("EStores");
    EntityManager entityManager = factory.createEntityManager();

}

}

Sample Entity Class

@Data
@Entity
@Table(name = "customer")
public class Customer {

@Id
@GeneratedValue
@Column(name = "customer_id")
private long id;

@Column(name = "first_name", nullable = false)
private String firstName;

@Column(name = "last_name", nullable = false)
private String lastName;

@Embedded
private Contact contact;

@Embedded
private Address address;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private Set<Review> reviews;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private Set<Product> products;


 public Customer(String firstName, String lastName, Contact contact,              
                                                  Address address) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.contact = contact;
    this.address = address;
    this.products = new HashSet<>();
    this.reviews = new HashSet<>();
}

}

Sonites
  • 41
  • 1
  • 3
  • if you are using JPA then you can set "spring.jpa.hibernate.ddl-auto" property in your application properties to "create" or "update" as per you need. You can read more about it here https://docs.spring.io/autorepo/docs/spring-boot/1.1.0.M1/reference/html/howto-database-initialization.html – vinay verma Jan 27 '20 at 12:51
  • Yes, This will work easily using spring framework and Eclipse IDE, but in this case I'm not using spring, It's a plain Java hibernate application and I'm using Intellij. – Sonites Jan 27 '20 at 23:02
  • I have just updated my question, please take a look. Thanks – Sonites Jan 27 '20 at 23:35
  • Are you looking for an option/feature in intellij idea ? I did not understand, you have ddlauto in your hbm that should create/update tables when you start your app – vinay verma Jan 28 '20 at 07:42
  • Sure, I actually wanted Intellij to create the tables from the entity classes the first time I run the application but I noticed it couldn't, So I had to create my database tables first and asked Intellij to generate the entity classes from the database tables of which it did. So Intellij only make uses of my hibernate config file to update my database when it detects any changes in the entity classes columns in subsequent running of the application. Thanks for the follow up. – Sonites Jan 30 '20 at 00:41

3 Answers3

5

I would suggest against using hbm2ddl.auto, instead you can add Liquibase to your project. It allows you to manage all of your DB schema modifications using changelogs, and you can run table generation/updates independently of your app start-up.

This does add an extra step between you modifying your model and the DB being updated, since you have to add all the changes to your changelogs. I'd recommend using JPA Buddy plugin for that, it can generate changelogs by comparing your Java model to your current database, here is how it looks

2

use JPA Buddy a IntelliJ IDEA plugin, it's free.

right click on your entity in JPA structure view then click show DDL.

Samt
  • 109
  • 8
1

If i am getting you right, you want to generate database tables from your Java classes right? If so, that's the main concept of ORM. Whenever you create a new POJO and annotate it with @Entity, you are telling hibernate to create a table using data from that class (if one doesn't exist). Find below an example that does just that:

package com.test.simple_crud_application.models;

import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;

@Entity
@Table(name = "users")
public class User implements Serializable
{
    @CreationTimestamp
    @Column(name = "created_at", updatable = false, nullable = false)
    private LocalDateTime createdAt;
    @UpdateTimestamp
    @Column(name = "updated_at", updatable = true, nullable = false)
    private LocalDateTime modifiedAt;

    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(name = "uid", unique = true, nullable = false)
    private String uid;

    @Column(name = "username", nullable = false)
    private String username;

    @Column(name = "password", nullable = false)
    private String password;
}
  • Sure, I have all my classes annotated like this already, It works fine in Eclipse with Spring. But it's not working in Intellij. I only got the option of generating Entity Classes from Database Tables Not generating Database Tables from Entity Classes. – Sonites Jan 27 '20 at 23:07
  • I have just updated my question, please take a look. Thanks – Sonites Jan 27 '20 at 23:35