在jpa/EclipseLink创建表后执行sql脚本?

ger*_*rry 13 java orm jpa eclipselink jpa-2.0

在EclipseLink生成ddl后,是否有可能执行sql脚本?
换句话说,是否可能使用带有"drop-and-create-tables"的EclipseLink属性"eclipselink.ddl-generation",并且EclipseLink在创建后执行另一个sql文件(将一些数据插入到刚创建的某些表中)表定义?

我正在使用带有GlassFish v3的EclipseLink 2.x和JPA 2.0.

或者我可以在项目调用的java方法(与ejb3的战争)部署中初始化表吗?

Fre*_*ing 17

我出于同样的原因遇到了这个问题,试图找到一种在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>
Run Code Online (Sandbox Code Playgroud)

上述配置从元数据(即注释)生成DDL脚本,然后META-INF/sql/load_script.sql运行脚本以填充数据库.在我的例子中,我使用测试数据生成几个表并生成其他视图.

有关EclipseLink使用JPA属性的更多信息,请参阅EclipseLink/Release/2.5/JPA21的DDL生成部分.同样,Oracle Java EE 7教程和TOTD#187中的第37.5节"数据库模式创建"也提供了快速入门.


Pas*_*ent 16

看一下在EclipseLink启动运行SQL脚本,它描述了一种与Hibernate的import.sql功能1等效的解决方案.致Shaun Smith的致谢:

在EclipseLink中启动时运行SQL脚本

有时,在使用DDL生成时,首先运行脚本来清理数据库是很有用的.在Hibernate中,如果在类路径中放置一个名为"import.sql"的文件,其内容将被发送到数据库.就个人而言,我不是魔术文件名的粉丝,但这可能是一个有用的功能.

EclipseLink中没有内置的支持,但感谢EclipseLink的高可扩展性.这是我提出的一个快速解决方案:我只是为会话postLogin事件注册一个事件监听器,在处理程序中我读取一个文件并将每个SQL语句发送到数据库 - 很好,干净.我更进一步,支持将文件名设置为持久性单元属性.您可以在代码或persistence.xml中指定all.

所述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() 
            }    
        });
    }
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是一个严格的等价,但我不确定脚本将在数据库生成后运行.需要测试.如果没有,也许它可以适应.

1 Hibernate有一个整洁的小功能,严重缺乏记录和未知.您可以在生成数据库模式之后立即在SessionFactory创建期间执行SQL脚本,以在新数据库中导入数据.您只需在类路径根目录中添加名为import.sql的文件,并将create或create-drop设置为hibernate.hbm2ddl.auto属性.


Car*_*vel 0

它被称为 BEFORE ddl-execution。而且似乎没有很好的方法来适应它,因为没有合适的事件可以使用。