有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

我用的是EclipseLink 2。x和JPA2.0以及GlassFish v3

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


共 (6) 个答案

  1. # 1 楼答案

    它在ddl执行之前被调用。而且似乎没有好的方法来适应它,因为没有合适的活动可以使用

  2. # 2 楼答案

    这个过程提供在DDL语句之前执行sql,而最好的方法(例如,插入种子数据)是在DDL语句之后执行sql。我不知道我是否遗漏了什么。有人能告诉我在eclipselink创建表之后如何执行sql吗(当CreateTables属性设置为tru时)

  3. # 3 楼答案

    这可能会有所帮助,因为这里有一个困惑: 对数据种子设定使用完全相同的属性集(记录器除外)

    不要使用:

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

    我确认这对我有效

  4. # 4 楼答案

    :)只需用数据替换即可

    <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"/>
    
  5. # 5 楼答案

    我遇到这个问题也是出于同样的原因,试图找到一种在生成DDL后运行初始化脚本的方法。我对一个老问题给出了这个答案,希望能为那些寻求同样解决方案的人缩短“文学研究”的数量

    我正在使用GlassFish4及其默认的EclipseLink 2.5JPA实现。JPA2.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属性的更多信息可以在EclipseLink/Release/2.5/JPA21的DDL生成部分找到。同样,Oracle的JavaEE7教程中的Section 37.5 Database Schema CreationTOTD #187也提供了一个快速介绍

  6. # 6 楼答案

    看看Running a SQL Script on startup in EclipseLink,它描述了一种与Hibernate的import.sql功能相当的解决方案。肖恩·史密斯的功劳:

    Running a SQL Script on startup in EclipseLink

    Sometimes, when working with DDL generation it's useful to run a script to clean up the database first. In Hibernate if you put a file called "import.sql" on your classpath its contents will be sent to the database. Personally I'm not a fan of magic filenames but this can be a useful feature.

    There's no built in support for this in EclipseLink but it's easy to do thank's to EclipseLink's high extensibility. Here's a quick solution I came up with: I simply register an event listener for the session postLogin event and in the handler I read a file and send each SQL statement to the database--nice and clean. I went a little further and supported setting the name of the file as a persistence unit property. You can specify this all in code or in the persistence.xml.

    The ImportSQL class is configured as a SessionCustomizer through a persistence unit property which, on the postLogin event, reads the file identified by the "import.sql.file" property. This property is also specified as a persistence unit property which is passed to createEntityManagerFactory. This example also shows how you can define and use your own persistence unit properties.

    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);
    }
    

    我不确定它是否是严格等效的,但我不确定脚本是否会在数据库生成后运行。需要测试。如果没有,也许它可以被改编

    1Hibernate有一个简洁的小功能,但它的文档记录严重不足且未知。您可以在数据库架构生成之后立即在SessionFactory创建期间执行SQL脚本,以将数据导入新数据库。您只需要添加一个名为import的文件。在类路径根中使用sql,并将create或create drop设置为hibernate。hbm2ddl。自动属性