在EclipseLink生成ddl后,是否有可能执行sql脚本? 换句话说,是否可能使用带有“drop-and-create-tables”的EclipseLink属性“eclipselink.ddl-generation”,并且EclipseLink在创建后执行另一个sql文件(将一些数据插入到刚创建的某些表中)表定义?
我正在使用带有GlassFish v3的EclipseLink 2.x和JPA 2.0。
或者我可以在项目中调用的java方法(与ejb3一起战争)中初始化表吗?
答案 0 :(得分:17)
我出于同样的原因遇到了这个问题,试图找到一种在DDL生成后运行初始化脚本的方法。我提出这个问题的答案,希望缩短那些寻求相同解决方案的人的“文学研究”数量。
我正在使用GlassFish 4及其默认的EclipseLink 2.5 JPA实现。 JPA 2.1下新的Schema Generation功能使得在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 Java EE 7教程中的Section 37.5 Database Schema Creation和TOTD #187也提供了快速介绍。
答案 1 :(得分:15)
查看Running a SQL Script on startup in EclipseLink,其中描述的解决方案与Hibernate的import.sql
功能 1 等效。 Shaun Smith的致谢:
Running a SQL Script on startup in EclipseLink
有时,使用DDL时 生成它对运行脚本很有用 首先清理数据库。在 如果你把一个文件叫做Hibernate 你的classpath上的“import.sql” 内容将被发送到数据库。 就个人而言,我不是魔术迷 文件名,但这可能是有用的 特征
没有内置的支持 在EclipseLink中,但它很容易做到 感谢EclipseLink的高度 可扩展性。这是一个快速的解决方案 我想出来了:我只是注册了一个 会话的事件侦听器 postLogin事件和处理程序中的I 读取文件并发送每个SQL 对数据库的声明 - 很好,而且 清洁。我走得更远了 支持设置文件名 作为持久性单元属性。您 可以在代码中或在。中指定全部 persistence.xml中。
ImportSQL
类配置为 aSessionCustomizer
到 持久性单位属性,在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有一个整洁的小功能,严重缺乏记录和未知。您可以在生成数据库模式之后立即在SessionFactory创建期间执行SQL脚本,以在新数据库中导入数据。您只需在类路径根目录中添加名为import.sql的文件,并将create或create-drop设置为hibernate.hbm2ddl.auto属性。
答案 2 :(得分:1)
这可能会有所帮助,因为这里有一个混乱: 使用完全相同的属性集(记录器除外)进行数据播种。
请勿使用:
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
DO USE:
<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"/>
我确认这对我有用。
答案 3 :(得分:0)
它被称为BEFORE ddl-execution。似乎没有很好的方法来适应它,因为没有合适的事件可以使用。
答案 4 :(得分:0)
此过程在DDL语句之前提供执行sql,而最好的(例如,插入种子数据)是在DDL语句之后执行的操作。如果我在这里错过了什么,我不会。有人可以告诉我如何在eclipselink创建表后执行sql(当create-tables属性设置为tru时)
答案 5 :(得分:0)
:)只需替换你的数据
<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"/>