简体   繁体   中英

How to load / insert initial data into database with Ebean in Play Framework?

I need to some initial data (from csv files) into database. I am using Ebean with Play! Framework. I read the doc . It says using YAML files to store the data and call Ebean.save(). And this is done in a Test.

My questions:

  1. Where should I insert my data? (Test is probably not the ideal place, as this data should be used in production)

  2. Can I write my own code to get my data from existing csv files, instead of using YAML files?

Any suggestions or doc links will be appreciated.

Thanks!

A Play Framework 2.4 solution to loading initial data on application startup, using Ebean:

First, create a class where you want perform the initial data load. According to the docs this has to be in the constructor.

public class InitialData {
    public InitialData() {

        if (Ebean.find(User.class).findRowCount() == 0) {
            InputStream is = this.getClass().getClassLoader().getResourceAsStream("initial-data.yml");

            @SuppressWarnings("unchecked")
            Map<String, List<Object>> all = 
                (Map<String, List<Object>>)Yaml.load(is, this.getClass().getClassLoader());

            //Yaml.load("initial-data.yml"); //calls Play.application() which isn't available yet
            Ebean.save(all.get("users"));
        }
    }
}

NOTE: I used Yaml's load(InputStream is, ClassLoader classloader) method over its load(String resourceName) method because it does not work. I believe this is because of its use of Play.application(), as this is not available before the application is started. Source Here

Second, According to Play docs, to execute code before startup, use Eager-bindings. This will cause your code in the InitialData constructor to execute.

public class MainModule extends AbstractModule implements AkkaGuiceSupport {
    @Override
    protected void configure() {
        //this is where the magic happens
        bind(InitialData.class).asEagerSingleton();
    }
}

Make sure to add your MainModule class to the application.conf

# modules
play.modules.enabled += "module.MainModule"

With further search, I found the solution is described here

The code that perform initial insertion needs to be hooked into Play's startup.

Hooking into Play's startup is as simple as creating a class called Global that implements GlobalSettings in the root package, and overriding the onStart() method. Let's do that now, by creating the app/Global.java fileHooking into Play's startup is as simple as creating a class called Global that implements GlobalSettings in the root package, and overriding the onStart() method. Let's do that now, by creating the app/Global.java file

Note that, it said the class needs to be in the root package.

code example:

import play.*;
import play.libs.*;
import com.avaje.ebean.Ebean;
import models.*;
import java.util.*;

public class Global extends GlobalSettings {
    @Override
    public void onStart(Application app) {
        // Check if the database is empty
        if (User.find.findRowCount() == 0) {
            Ebean.save((List) Yaml.load("initial-data.yml")); // You can use whatever data source you have here. No need to be in YAML.
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM