Выполнить SQL-скрипт после создания таблиц jpa/EclipseLink?

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

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

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

6 ответов


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


я столкнулся с этим вопросом по тем же причинам, пытаясь найти подход для запуска сценария инициализации после генерации 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 Схема Базы Данных Творение в учебнике Java EE 7 Oracle и TOTD #187 предложите быстрое введение также.


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

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

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

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

на ImportSQL класс настроен как а SessionCustomizer через a свойство единицы персистентности, которое the postLogin событие, считывает файл идентифицируется по "import.язык SQL.файл" свойство. Это свойство также задано как единица персистентности свойство, которое передается 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 сразу после создания схемы базы данных для импорта данных в новую базу данных. Вам просто нужно добавить в файл импорта.sql в корневом каталоге пути к классам и установите create или create-drop в качестве спящего режима.hbm2ddl.свойство auto.


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

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

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

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


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


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

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