Выполнить сценарий sql после того, как jpa / EclipseLink создал таблицы? - PullRequest
13 голосов
/ 28 апреля 2010

есть ли возможность выполнить сценарий sql после того, как EclipseLink сгенерировал ddl?
Другими словами, возможно ли использование свойства EclipseLink «eclipselink.ddl-generation» с «drop-and-create-tables» и EclipseLink выполняет другой sql-файл (для вставки данных в некоторые только что созданные таблицы) после создания определение таблицы?

Я использую EclipseLink 2.x и JPA 2.0 с GlassFish v3.

Или я могу инициализировать таблицы в java-методе, который вызывается при развертывании проекта (война с ejb3)?

Ответы [ 6 ]

17 голосов
/ 13 февраля 2014

Я сталкивался с этим вопросом по тем же причинам, пытаясь найти подход для запуска сценария инициализации после генерации DDL. Я предлагаю этот ответ на старый вопрос в надежде сократить количество «литературных исследований» для тех, кто ищет то же решение.

Я использую GlassFish 4 со стандартной реализацией EclipseLink 2.5 JPA. Новая функция генерации схемы в JPA 2.1 позволяет довольно просто указать сценарий «инициализации» после завершения генерации DDL.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="cbesDatabase" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>java:app/jdbc/cbesPool</jta-data-source>
        <properties>
            <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/sql/load_script.sql"/>
            <property name="eclipselink.logging.level" value="FINE"/> 
        </properties>
    </persistence-unit>
</persistence>

Приведенная выше конфигурация генерирует сценарии DDL из метаданных (т.е. аннотаций), после чего запускается сценарий META-INF/sql/load_script.sql для заполнения базы данных. В моем случае я заполняю несколько таблиц с тестовыми данными и генерирую дополнительные представления.

Дополнительную информацию об использовании EclipseLink свойств JPA можно найти в разделе «Генерация DDL» EclipseLink / Release / 2.5 / JPA21 . Аналогичным образом, Раздел 37.5 Создание схемы базы данных в Oracle EE 7 Tutorial и TOTD # 187 также предлагают краткое введение.

15 голосов
/ 28 апреля 2010

Взгляните на Запуск сценария SQL при запуске в EclipseLink , который описывает решение, представленное как своего рода эквивалент import.sql функции Hibernate 1 . Кредиты Шон Смит:

Запуск сценария SQL при запуске в EclipseLink

Иногда при работе с DDL поколение полезно запустить скрипт сначала очистить базу данных. В Hibernate, если вы положили файл с именем "import.sql" на вашем пути к классам его содержимое будет отправлено в базу данных. Лично я не фанат магии имена файлов, но это может быть полезным особенность.

Там нет встроенной поддержки для этого в EclipseLink, но это легко сделать спасибо EclipseLink's высоко расширяемость. Вот быстрое решение Я придумал: я просто регистрирую прослушиватель событий для сеанса событие postLogin и в обработчике I прочитать файл и отправить каждый SQL постановка в базу данных - красиво и чистый. Я пошел немного дальше и поддерживается настройка имени файла как свойство единицы сохраняемости. Вы можете указать все это в коде или в persistence.xml.

Класс ImportSQL настроен как SessionCustomizer через свойство единицы сохраняемости, которое на postLogin событие, читает файл идентифицируется "import.sql.file" имущество. Это свойство также указывается как единица постоянства свойство, которое передается createEntityManagerFactory. это Пример также показывает, как вы можете определить и использовать свой собственный блок персистентности свойства.

import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;
import org.eclipse.persistence.sessions.UnitOfWork;

public class ImportSQL implements SessionCustomizer {

    private void importSql(UnitOfWork unitOfWork, String fileName) {
        // Open file
        // Execute each line, e.g.,
        // unitOfWork.executeNonSelectingSQL("select 1 from dual");
    }

    @Override
    public void customize(Session session) throws Exception {
        session.getEventManager().addListener(new SessionEventAdapter() {
            @Override
            public void postLogin(SessionEvent event) {
                String fileName = (String) event.getSession().getProperty("import.sql.file");
                UnitOfWork unitOfWork = event.getSession().acquireUnitOfWork();
                importSql(unitOfWork, fileName);
                unitOfWork.commit() 
            }    
        });
    }

public static void main(String[] args) {
    Map<String, Object> properties = new HashMap<String, Object>();

    // Enable DDL Generation
    properties.put(PersistenceUnitProperties.DDL_GENERATION, PersistenceUnitProperties.DROP_AND_CREATE);
    properties.put(PersistenceUnitProperties.DDL_GENERATION_MODE, PersistenceUnitProperties.DDL_DATABASE_GENERATION);
    // Configure Session Customizer which will pipe sql file to db before DDL Generation runs
    properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, "model.ImportSQL");
    properties.put("import.sql.file","/tmp/someddl.sql");

    EntityManagerFactory emf = Persistence
            .createEntityManagerFactory("employee", properties);
}

Хотя я не уверен, что это строгий эквивалент, я не уверен, что скрипт будет запущен после генерации базы данных. Требуется тестирование. Если это не так, может быть, это можно адаптировать.

1 Hibernate имеет изящную небольшую функцию, которая сильно недокументирована и неизвестна. Вы можете выполнить сценарий SQL во время создания SessionFactory сразу после создания схемы базы данных, чтобы импортировать данные в новую базу данных. Вам просто нужно добавить файл с именем import.sql в корневой каталог classpath и установить либо create, либо create-drop в качестве свойства hibernate.hbm2ddl.auto.

1 голос
/ 12 октября 2014

Это может помочь, так как здесь есть путаница: Используйте точно такой же набор свойств (кроме логгера) для заполнения данных.

НЕ ИСПОЛЬЗОВАТЬ:

<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="database"/>

ИСПОЛЬЗУЙТЕ:

<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"/>

Я подтверждаю, что это сработало для меня.

0 голосов
/ 09 декабря 2015

:) Просто замените ваши данные

<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation.create-source" value="metadata-then-script"/>
<property name="javax.persistence.sql-load-script-source" value="META-INF/seed.sql"/>
0 голосов
/ 18 февраля 2011

Этот процесс предлагает выполнить sql перед DDL-проверкой, тогда как было бы неплохо (например, вставить начальные данные) что-то, что выполняется после DDL-операторов. Я не, если я что-то здесь упускаю. Может кто-нибудь, пожалуйста, скажите мне, как выполнить sql ПОСЛЕ того, как eclipselink создал таблицы (когда свойство create-tables установлено в tru)

0 голосов
/ 29 августа 2010

Это называется ДО ddl-исполнения. И, похоже, нет подходящего способа адаптировать его, поскольку нет подходящего события, которое можно было бы использовать.

...