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

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

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

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

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

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

我正在使用GlassFish 4及其默认的EclipseLink 2.5 JPA实现。 JPA 2.1下的新模式生成function使得在DDL生成完成后指定“初始化”脚本非常简单。

   org.eclipse.persistence.jpa.PersistenceProvider java:app/jdbc/cbesPool          

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

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

看一下在EclipseLink中启动时运行一个SQL脚本,它描述了一个与Hibernate的import.sql特性相当的解决方案1 。 Shaun Smith的致辞:

在EclipseLink中启动时运行SQL脚本

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

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, eg, // 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 properties = new HashMap(); // 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有一个整洁的小function,严重缺乏记录和未知。 您可以在生成数据库模式之后立即在SessionFactory创建期间执行SQL脚本,以在新数据库中导入数据。 您只需在类路径根目录中添加名为import.sql的文件,并将create或create-drop设置为hibernate.hbm2ddl.auto属性。

这可能有所帮助,因为这里存在混淆:使用完全相同的属性集(记录器除外)进行数据种子设定。

不使用:

   

使用方法:

    

我确认这对我有用。

此过程在DDL语句之前提供执行sql,而最好的(例如,插入种子数据)是在DDL语句之后执行的操作。 如果我在这里遗漏了什么,我不会。 有人可以告诉我如何在eclipselink创建表后执行sql(当create-tables属性设置为tru时)

:)只需替换你的数据