In SpringBoot Java application, if you define spring.jpa.hibernate.ddl-auto = create-drop
or DDL setting value in application.properties, the table will be automatically generated.
I created a gradle task that automatically generates DDL because it is inflexible in scenes such as "It is dropped every time and the data is initialized" or "For migration, DDL is necessary for some reason".
A good plugin jpa-schema-gradle-plugin has been released, so I will use it. This plugin reads the Entity class under the specified package (packageToScan setting value) and creates DDL.
Spring Boot gradle (It is assumed that you understand how to use build.gradle.)
__1. App settings for plugin calls __
Define the required setting values according to How to Use of jpa-schema-gradle-plugin. This time, my DB is Oracle and OR mapper is Hibernate, so the final final settings are as follows.
build.gradle
plugins {
id 'io.github.divinespear.jpa-schema-generate' version '0.3.6'
}
dependencies {
implementation 'com.oracle.database.jdbc:ojdbc8:19.8.0.0'
}
generateSchema {
vendor = 'hibernate'
packageToScan = ['com.example.domain'] //Directly specify the directory of your own gradle project or domain.
databaseProductName = 'Oracle12'
scriptAction = 'drop-and-create' //drop.sql and create.sql is created.
properties = [
'hibernate.dialect': 'org.hibernate.dialect.Oracle12cDialect',
'hibernate.physical_naming_strategy': 'org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy', //in column name"_"To enter.
'hibernate.implicit_naming_strategy': 'org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy'
]
}
__2. Preparation of Entity __ Entity prepared Customer.java and SpringUser.java in src/main/java/com/example/domain/for the following.
Customer.java
package com.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "CUSTOMER")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_CUSTOMER_GENERATOR")
@SequenceGenerator(name = "SEQ_CUSTOMER_GENERATOR", sequenceName = "SEQ_CUSTOMER", allocationSize = 1)
private Integer id;
@Column
private String firstName;
@Column
private String lastName;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(nullable = true, name = "USER_NAME")
private SpringUser user;
}
SpringUser.java
package com.example.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "SPRING_USER")
@ToString(exclude = "customers") //This is the field variable customers
public class SpringUser {
@Id
private String userName;
@JsonIgnore
private String encodedPassword;
@JsonIgnore
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private List<Customer> customers;
}
After creating the build.gradle above, don't forget to run "Refresh all Gradle Projects" (adding a gradle task).
If you run gradle generateSchema
from the terminal, build/generated-schema/create.sql will be created (default output destination).
Here is the completed create.sql. As defined in Customer.java, SEQUENCE is also created by reflecting it properly. Whether or not to put "_" in the physical name of the column can be changed with the value "SpringPhysicalNamingStrategy" set in build.gradle, so detailed specifications can be found in jpa-schema-gradle-plugin How I think you should read to Use.
create.sql
create sequence seq_customer start with 1 increment by 1;
create table customer (id number(10,0) not null, first_name varchar2(255 char), last_name varchar2(255 char), user_name varchar2(255 char), primary key (id));
create table spring_user (user_name varchar2(255 char) not null, encoded_password varchar2(255 char), primary key (user_name));
alter table customer add constraint FKc7gvbu1i8l83wyt8q39egdfka foreign key (user_name) references spring_user;
** Trouble 1: KotlinNullPointerException **
If you look at How to Use of jpa-schema-gradle-plugin,
The minimum setting value when persistence.xml is not used is
vendor = 'hibernate'
packageToScan = ['com.example.domain']
It looks like just this, but when I run generateSchema I get a KotlinNullPointerException.
⇒ Solution: You need to set databaseProductName.
** Trouble 2: generateSchema is registered in gradle task, but create.sql is not created even if it is executed **
It was an easy mistake. I just missed scriptAction ='drop-and-create'
.
By automatically generating DDL, it is possible to smoothly build the environment of the project participating members, so it is recommended to install this plug-in. Well, recently, you can easily generate DDL automatically and simplify migration by using flyway, but you can lower the hurdle when incorporating new technology by creating a plugin by yourself or following it. I think.
Thank you for reading this far. : bow:
Recommended Posts