blackbox_devops
blackbox_devops

Reputation: 25

How to add Hard-coded Data to Spring Boot Project so it's in Database after Running

I apologize about the title of the question. I was exactly sure how to word the question.

A little background: I'm fairly new to Spring, so there's fairly a lot of things Spring-related that go completely over my head. I recently started a new practice project where I create an inventory application for medicines. As of now, I have my models and repositories set up. I've decided to implement a PostgreSQL database.

I've worked on a few Spring projects in the past, and if I'm remembering correctly, you can hardcode some instances of the models that you've created for testing purposes. So, when you run the Spring boot application, these instances will already be in the database, so I wouldn't have to add it through pgAdmin or the sql shell myself after the fact.

I'm confused as to where exactly I would "hard-code" this information and whether or not it would be in JSON format. I think it would go in the main function of my InventoryApplication.java because that's where my spring boot program is being run, but I'm unsure.

Here's a few of my files in order to understand the flow of my project:

InventoryApplication.java

package com.oasis.inventory;
import com.oasis.inventory.model.*;
import com.oasis.inventory.repository.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class InventoryApplication {

    public static void main(String[] args) {
        SpringApplication.run(InventoryApplication.class, args);
    }
}

pharmaceutical.java

package com.oasis.inventory.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.*;

@Entity
@Table(name = "pharmaceuticals")
public class Pharmaceutical {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    
    @Column(name = "genericName")
    private String genericName;
    
    @Column(name = "brandNames")
    private ArrayList<String> brandNames;
    
    @Column(name = "strength" )
    private String strength;
    
    @Column(name = "quantity")
    private int quantity; 
    
    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                CascadeType.PERSIST,
                CascadeType.MERGE
            })
    
    @JoinTable(name = "pharm_commonuses",
        joinColumns = { @JoinColumn(name = "pharmaceutical_id") },
        inverseJoinColumns = { @JoinColumn(name = "commonUse_id") })
    private Set<CommonUse> commonUses = new HashSet<>();
    
    public Pharmaceutical() {}
        
    public Pharmaceutical(String genericName, ArrayList<String> brandNames, String strength,
            int quantity) {
        this.genericName = genericName;
        this.brandNames = brandNames;
        this.strength = strength;
        this.quantity = quantity;
    }

    public String getGenericName() {
        return genericName;
    }

    public void setGenericName(String genericName) {
        this.genericName = genericName;
    }

    public ArrayList<String> getBrandNames() {
        return brandNames;
    }

    public void setBrandNames(ArrayList<String> brandNames) {
        this.brandNames = brandNames;
    }

    public String getStrength() {
        return strength;
    }

    public void setStrength(String strength) {
        this.strength = strength;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public long getId() {
        return id;
    }

    @Override
    public String toString() {
        return "Pharmaceutical [id=" + id + ", genericName=" + genericName + ", brandNames=" + brandNames
                + ", strength=" + strength + ", quantity=" + quantity + ", commonUses=" + commonUses + "]";
    }

    public Set<CommonUse> getCommonUses() {
        return commonUses;
    }
        
}

application.properties

server.port=8081

spring.datasource.initialization-mode=always
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.username=postgres
spring.datasource.password= sEcReT

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect

# Hibernate ddl auto (create, create-drop, validate, update)
# For prod, change to validate
spring.jpa.hibernate.ddl-auto= update

pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.oasis</groupId>
    <artifactId>inventory</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>inventory</name>
    <description>pharmaceuticals inventory management system</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Upvotes: 1

Views: 2645

Answers (1)

Rye
Rye

Reputation: 485

It's close to a 2 year old question and I believe you have come up with a solution. I still wanted to share just in case someone would be looking for the same.

You can use CommandLineRunner to execute a transaction like persisting a record into the database. However, every time your application starts up it will always execute this and will lead to unwanted side effects but you can try it in your local development.

As @martinspielmann recommended, you can use FlywayDB or Liquibase to do the job. You can create versioned SQL files that may contain several queries for different transactions (CRUD) including database operations like creating/alter tables and more.

Upvotes: 1

Related Questions