JPA + Spring如何使用自定义表和数据初始化数据库

时间:2013-01-15 09:32:31

标签: database spring jpa acl

在我的应用程序中,我使用Spring上下文和JPA。我有一些用@Entity注释的实体集,并且在系统启动期间会自动创建表。最近我开始使用Spring ACL,所以我必须拥有following additional DB schema并且我不希望这些表被映射到实体(简单地说我不需要它们,因为Spring ACL独立地管理它们)。

  1. 我想自动插入,例如管理员用户帐户进入 User的实体表。如何正确地做到这一点?
  2. 我想在系统启动期间初始化Spring ACL自定义表,但SQL脚本文件似乎不是很好的解决方案,因为如果我使用不同的数据库进行生产和功能测试,则不同的SQL方言不允许我执行脚本适当地在两个引擎上(例如,当使用MySQL和HSQL时)。
  3. 起初我尝试使用ServletListener在servlet初始化期间检查数据库并添加必要的数据和模式,但这不适用于集成测试(因为根本没有涉及servlet)。

    我想要实现的是在JPA初始化所有实体表之后启动的Spring bean(?),使用注入的DAO插入所有启动数据并以某种方式创建Spring ACL模式。然后 - 我希望从IoC中删除bean(因为我不再需要它了)。有可能吗?

    或者有更好的方法吗?

4 个答案:

答案 0 :(得分:1)

如果您正在使用EclipseLink,则可以在JPA登录后使用SessionEventListener来执行代码。您可以在postLogin事件中执行模式创建和设置。

您可以使用EclipseLink中的Schema Framework(org.eclipse.persistence.tools.schemaframework)以独立于数据库平台的方式创建表和DDL。 (TableDefinition,SchemaManager类)

答案 1 :(得分:1)

我使用PostConstruct注释来调用初始化方法。

正如所描述的文档: PostConstruct注释用于在完成依赖注入以执行任何初始化之后需要执行的方法。您可以简单地添加带有@PostConstruct注释的方法的弹出框。在它上面,这些方法将在创建表之后执行(或者我们可以说,它们是在其他bean准备就绪后执行的。)

代码示例:

@Component
public class EntityLoader {

    @Autowired
    UserRepository userRepo;

    @PostConstruct
    public void initApiUserData() {
        User u = new User();
        // set user properties here
        userRepo.save(u);
    }

}

答案 2 :(得分:0)

如果使用hibernate,则在类路径根目录中创建一个sql脚本import.sql。 Hibernat将在启动时执行它。 - 这适用于以前的hibernate版本。在当前版本4.1的文档中,我没有找到任何关于此功能的提示。

但Hibernate 4.1还有其他功能

财产:hibernate.hbm2ddl.import_files

  

包含在SessionFactory创建期间执行的SQL DML语句的可选文件的逗号分隔名称。这对于测试或演示非常有用:例如,通过添加INSERT语句,您可以在部署数据库时使用最少的数据集填充数据库。   文件顺序很重要,给定文件的语句在以下文件的语句之前执行。这些语句仅在创建模式时执行,即如果hibernate.hbm2ddl.auto设置为create或create-drop。

     

e.g。 /humans.sql,/dogs.sql

答案 3 :(得分:0)

您可以尝试使用flyway

  • 使用SQL DDL作为SQL迁移和
  • 创建表
  • 可能使用基于SQL或Java的迁移在表中放置一些数据。如果需要环境或其他信息,您可能希望使用后者。

它比听起来容易得多,如果不是必须的话,你最终还会将flyway本身作为奖励。